1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Texture color conversion tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktYCbCrConversionTests.hpp"
26 #include "vktShaderExecutor.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29 #include "vktYCbCrUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkQueryUtil.hpp"
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"
47 #include "deRandom.hpp"
48 #include "deSTLUtil.hpp"
49 #include "deSharedPtr.hpp"
52 #include "deFloat16.h"
57 // \todo When defined color conversion extension is not used and conversion is performed in the shader
58 // #define FAKE_COLOR_CONVERSION
73 using tcu::FloatFormat;
78 using namespace vkt::shaderexecutor;
86 typedef de::SharedPtr<vk::Unique<vk::VkBuffer> > VkBufferSp;
87 typedef de::SharedPtr<vk::Allocation> AllocationSp;
89 // \note Used for range expansion
90 UVec4 getBitDepth (vk::VkFormat format)
94 case vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
95 case vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
96 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
97 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
98 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
99 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
100 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
101 return UVec4(8, 8, 8, 0);
103 case vk::VK_FORMAT_R10X6_UNORM_PACK16_KHR:
104 return UVec4(10, 0, 0, 0);
106 case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
107 return UVec4(10, 10, 0, 0);
109 case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
110 return UVec4(10, 10, 10, 10);
112 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
113 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
114 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
115 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
116 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
117 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
118 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
119 return UVec4(10, 10, 10, 0);
121 case vk::VK_FORMAT_R12X4_UNORM_PACK16_KHR:
122 return UVec4(12, 0, 0, 0);
124 case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
125 return UVec4(12, 12, 0, 0);
127 case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
128 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
129 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
130 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
131 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
132 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
133 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
134 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
135 return UVec4(12, 12, 12, 12);
137 case vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
138 case vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
139 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
140 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
141 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
142 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
143 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
144 return UVec4(16, 16, 16, 0);
147 return tcu::getTextureFormatBitDepth(vk::mapVkFormat(format)).cast<deUint32>();
151 // \note Taken from explicit lod filtering tests
152 FloatFormat getFilteringPrecision (vk::VkFormat format)
154 const FloatFormat reallyLow (0, 0, 6, false, tcu::YES);
155 const FloatFormat low (0, 0, 7, false, tcu::YES);
156 const FloatFormat fp16 (-14, 15, 10, false);
157 const FloatFormat fp32 (-126, 127, 23, true);
161 case vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16:
162 case vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16:
163 case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
164 case vk::VK_FORMAT_B5G6R5_UNORM_PACK16:
165 case vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16:
166 case vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16:
167 case vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16:
170 case vk::VK_FORMAT_R8G8B8_UNORM:
171 case vk::VK_FORMAT_B8G8R8_UNORM:
172 case vk::VK_FORMAT_R8G8B8A8_UNORM:
173 case vk::VK_FORMAT_B8G8R8A8_UNORM:
174 case vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32:
175 case vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
176 case vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
177 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
178 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
179 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
180 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
181 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
184 case vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32:
185 case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
186 case vk::VK_FORMAT_R16G16B16_UNORM:
187 case vk::VK_FORMAT_R16G16B16A16_UNORM:
188 case vk::VK_FORMAT_R10X6_UNORM_PACK16_KHR:
189 case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
190 case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
191 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
192 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
193 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
194 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
195 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
196 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
197 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
198 case vk::VK_FORMAT_R12X4_UNORM_PACK16_KHR:
199 case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
200 case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
201 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
202 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
203 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
204 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
205 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
206 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
207 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
208 case vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
209 case vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
210 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
211 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
212 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
213 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
214 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
218 DE_FATAL("Precision not defined for format");
223 // \note Taken from explicit lod filtering tests
224 FloatFormat getConversionPrecision (vk::VkFormat format)
226 const FloatFormat reallyLow (0, 0, 8, false, tcu::YES);
227 const FloatFormat fp16 (-14, 15, 10, false);
228 const FloatFormat fp32 (-126, 127, 23, true);
232 case vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16:
233 case vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16:
234 case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
235 case vk::VK_FORMAT_B5G6R5_UNORM_PACK16:
236 case vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16:
237 case vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16:
238 case vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16:
241 case vk::VK_FORMAT_R8G8B8_UNORM:
242 case vk::VK_FORMAT_B8G8R8_UNORM:
243 case vk::VK_FORMAT_R8G8B8A8_UNORM:
244 case vk::VK_FORMAT_B8G8R8A8_UNORM:
245 case vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32:
246 case vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
247 case vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
248 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
249 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
250 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
251 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
252 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
255 case vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32:
256 case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
257 case vk::VK_FORMAT_R16G16B16_UNORM:
258 case vk::VK_FORMAT_R16G16B16A16_UNORM:
259 case vk::VK_FORMAT_R10X6_UNORM_PACK16_KHR:
260 case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
261 case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
262 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
263 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
264 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
265 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
266 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
267 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
268 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
269 case vk::VK_FORMAT_R12X4_UNORM_PACK16_KHR:
270 case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
271 case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
272 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
273 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
274 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
275 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
276 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
277 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
278 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
279 case vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
280 case vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
281 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
282 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
283 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
284 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
285 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
289 DE_FATAL("Precision not defined for format");
297 ChannelAccess (tcu::TextureChannelClass channelClass,
300 const IVec3& bitPitch,
304 const IVec3& getSize (void) const { return m_size; }
305 const IVec3& getBitPitch (void) const { return m_bitPitch; }
306 void* getDataPtr (void) const { return m_data; }
308 Interval getChannel (const FloatFormat& conversionFormat,
309 const IVec3& pos) const;
310 deUint32 getChannelUint (const IVec3& pos) const;
311 float getChannel (const IVec3& pos) const;
312 void setChannel (const IVec3& pos, deUint32 x);
313 void setChannel (const IVec3& pos, float x);
316 const tcu::TextureChannelClass m_channelClass;
317 const deUint8 m_channelSize;
319 const IVec3 m_bitPitch;
321 const deInt32 m_bitOffset;
325 ChannelAccess::ChannelAccess (tcu::TextureChannelClass channelClass,
328 const IVec3& bitPitch,
331 : m_channelClass (channelClass)
332 , m_channelSize (channelSize)
334 , m_bitPitch (bitPitch)
336 , m_data ((deUint8*)data + (bitOffset / 8))
337 , m_bitOffset (bitOffset % 8)
341 //! Extend < 32b signed integer to 32b
342 inline deInt32 signExtend (deUint32 src, int bits)
344 const deUint32 signBit = 1u << (bits-1);
346 src |= ~((src & signBit) - 1);
351 deUint32 divRoundUp (deUint32 a, deUint32 b)
359 deUint32 ChannelAccess::getChannelUint (const IVec3& pos) const
361 DE_ASSERT(pos[0] < m_size[0]);
362 DE_ASSERT(pos[1] < m_size[1]);
363 DE_ASSERT(pos[2] < m_size[2]);
365 const deInt32 bitOffset (m_bitOffset + tcu::dot(m_bitPitch, pos));
366 const deUint8* const firstByte = ((const deUint8*)m_data) + (bitOffset / 8);
367 const deUint32 byteCount = divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u);
368 const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);
369 const deUint32 offset = bitOffset % 8;
372 deMemcpy(&bits, firstByte, byteCount);
374 return (bits >> offset) & mask;
377 void ChannelAccess::setChannel (const IVec3& pos, deUint32 x)
379 DE_ASSERT(pos[0] < m_size[0]);
380 DE_ASSERT(pos[1] < m_size[1]);
381 DE_ASSERT(pos[2] < m_size[2]);
383 const deInt32 bitOffset (m_bitOffset + tcu::dot(m_bitPitch, pos));
384 deUint8* const firstByte = ((deUint8*)m_data) + (bitOffset / 8);
385 const deUint32 byteCount = divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u);
386 const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);
387 const deUint32 offset = bitOffset % 8;
389 const deUint32 bits = (x & mask) << offset;
390 deUint32 oldBits = 0;
392 deMemcpy(&oldBits, firstByte, byteCount);
395 const deUint32 newBits = bits | (oldBits & (~(mask << offset)));
397 deMemcpy(firstByte, &newBits, byteCount);
401 float ChannelAccess::getChannel (const IVec3& pos) const
403 const deUint32 bits (getChannelUint(pos));
405 switch (m_channelClass)
407 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
408 return (float)bits / (float)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u));
410 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
413 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
414 return de::max(-1.0f, (float)signExtend(bits, m_channelSize) / (float)((0x1u << (m_channelSize - 1u)) - 1u));
416 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
417 return (float)signExtend(bits, m_channelSize);
419 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
420 if (m_channelSize == 32)
421 return tcu::Float32(bits).asFloat();
424 DE_FATAL("Float type not supported");
429 DE_FATAL("Unknown texture channel class");
434 Interval ChannelAccess::getChannel (const FloatFormat& conversionFormat,
435 const IVec3& pos) const
437 const deUint32 bits (getChannelUint(pos));
439 switch (m_channelClass)
441 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
442 return conversionFormat.roundOut(conversionFormat.roundOut((double)bits, false)
443 / conversionFormat.roundOut((double)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u)), false), false);
445 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
446 return conversionFormat.roundOut((double)bits, false);
448 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
450 const Interval result (conversionFormat.roundOut(conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false)
451 / conversionFormat.roundOut((double)((0x1u << (m_channelSize - 1u)) - 1u), false), false));
453 return Interval(de::max(-1.0, result.lo()), de::max(-1.0, result.hi()));
456 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
457 return conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false);
459 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
460 if (m_channelSize == 32)
461 return conversionFormat.roundOut(tcu::Float32(bits).asFloat(), false);
464 DE_FATAL("Float type not supported");
469 DE_FATAL("Unknown texture channel class");
474 // \todo Taken from tcuTexture.cpp
475 // \todo [2011-09-21 pyry] Move to tcutil?
476 template <typename T>
477 inline T convertSatRte (float f)
479 // \note Doesn't work for 64-bit types
480 DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64));
481 DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0));
483 deInt64 minVal = std::numeric_limits<T>::min();
484 deInt64 maxVal = std::numeric_limits<T>::max();
485 float q = deFloatFrac(f);
486 deInt64 intVal = (deInt64)(f-q);
496 // else Don't add anything
499 intVal = de::max(minVal, de::min(maxVal, intVal));
504 void ChannelAccess::setChannel (const IVec3& pos, float x)
506 DE_ASSERT(pos[0] < m_size[0]);
507 DE_ASSERT(pos[1] < m_size[1]);
508 DE_ASSERT(pos[2] < m_size[2]);
510 const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u);
512 switch (m_channelClass)
514 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
516 const deUint32 maxValue (mask);
517 const deUint32 value (de::min(maxValue, (deUint32)convertSatRte<deUint32>(x * (float)maxValue)));
518 setChannel(pos, value);
522 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
524 const deInt32 range ((0x1u << (m_channelSize - 1u)) - 1u);
525 const deUint32 value ((deUint32)de::clamp<deInt32>(convertSatRte<deInt32>(x * (float)range), -range, range));
526 setChannel(pos, value);
530 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
532 const deUint32 maxValue (mask);
533 const deUint32 value (de::min(maxValue, (deUint32)x));
534 setChannel(pos, value);
538 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
540 const deInt32 minValue (-(deInt32)(1u << (m_channelSize - 1u)));
541 const deInt32 maxValue ((deInt32)((1u << (m_channelSize - 1u)) - 1u));
542 const deUint32 value ((deUint32)de::clamp((deInt32)x, minValue, maxValue));
543 setChannel(pos, value);
547 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
549 if (m_channelSize == 32)
551 const deUint32 value = tcu::Float32(x).bits();
552 setChannel(pos, value);
555 DE_FATAL("Float type not supported");
560 DE_FATAL("Unknown texture channel class");
564 ChannelAccess getChannelAccess (MultiPlaneImageData& data,
565 const vk::PlanarFormatDescription& formatInfo,
569 DE_ASSERT(formatInfo.hasChannelNdx(channelNdx));
571 const deUint32 planeNdx = formatInfo.channels[channelNdx].planeNdx;
572 const deUint32 valueOffsetBits = formatInfo.channels[channelNdx].offsetBits;
573 const deUint32 pixelStrideBytes = formatInfo.channels[channelNdx].strideBytes;
574 const deUint32 pixelStrideBits = pixelStrideBytes * 8;
575 const deUint8 sizeBits = formatInfo.channels[channelNdx].sizeBits;
577 DE_ASSERT(size.x() % formatInfo.planes[planeNdx].widthDivisor == 0);
578 DE_ASSERT(size.y() % formatInfo.planes[planeNdx].heightDivisor == 0);
580 deUint32 accessWidth = size.x() / formatInfo.planes[planeNdx].widthDivisor;
581 const deUint32 accessHeight = size.y() / formatInfo.planes[planeNdx].heightDivisor;
582 const deUint32 elementSizeBytes = formatInfo.planes[planeNdx].elementSizeBytes;
584 const deUint32 rowPitch = formatInfo.planes[planeNdx].elementSizeBytes * accessWidth;
585 const deUint32 rowPitchBits = rowPitch * 8;
587 if (pixelStrideBytes != elementSizeBytes)
589 DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0);
590 accessWidth *= elementSizeBytes/pixelStrideBytes;
593 return ChannelAccess((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type, sizeBits, IVec3(accessWidth, accessHeight, 1u), IVec3((int)pixelStrideBits, (int)rowPitchBits, 0), data.getPlanePtr(planeNdx), (deUint32)valueOffsetBits);
596 ShaderSpec createShaderSpec (void)
600 spec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=0) uniform highp sampler2D u_sampler;";
602 spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
603 spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
605 spec.source = "o_color = texture(u_sampler, uv);\n";
610 void genTexCoords (std::vector<Vec2>& coords,
613 for (deUint32 y = 0; y < size.y() + (size.y() / 2); y++)
614 for (deUint32 x = 0; x < size.x() + (size.x() / 2); x++)
616 const float fx = (float)x;
617 const float fy = (float)y;
619 const float fw = (float)size.x();
620 const float fh = (float)size.y();
622 const float s = 1.5f * ((fx * 1.5f * fw + fx) / (1.5f * fw * 1.5f * fw)) - 0.25f;
623 const float t = 1.5f * ((fy * 1.5f * fh + fy) / (1.5f * fh * 1.5f * fh)) - 0.25f;
625 coords.push_back(Vec2(s, t));
629 Interval rangeExpandChroma (vk::VkSamplerYcbcrRangeKHR range,
630 const FloatFormat& conversionFormat,
632 const Interval& sample)
634 const deUint32 values (0x1u << bits);
638 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR:
639 return conversionFormat.roundOut(sample - conversionFormat.roundOut(Interval((double)(0x1u << (bits - 1u)) / (double)((0x1u << bits) - 1u)), false), false);
641 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR:
643 const Interval a (conversionFormat.roundOut(sample * Interval((double)(values - 1u)), false));
644 const Interval dividend (conversionFormat.roundOut(a - Interval((double)(128u * (0x1u << (bits - 8u)))), false));
645 const Interval divisor ((double)(224u * (0x1u << (bits - 8u))));
646 const Interval result (conversionFormat.roundOut(dividend / divisor, false));
652 DE_FATAL("Unknown YCbCrRange");
657 Interval rangeExpandLuma (vk::VkSamplerYcbcrRangeKHR range,
658 const FloatFormat& conversionFormat,
660 const Interval& sample)
662 const deUint32 values (0x1u << bits);
666 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR:
667 return conversionFormat.roundOut(sample, false);
669 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR:
671 const Interval a (conversionFormat.roundOut(sample * Interval((double)(values - 1u)), false));
672 const Interval dividend (conversionFormat.roundOut(a - Interval((double)(16u * (0x1u << (bits - 8u)))), false));
673 const Interval divisor ((double)(219u * (0x1u << (bits - 8u))));
674 const Interval result (conversionFormat.roundOut(dividend / divisor, false));
680 DE_FATAL("Unknown YCbCrRange");
685 Interval clampMaybe (const Interval& x,
691 DE_ASSERT(min <= max);
694 result = result | Interval(min);
697 result = result | Interval(max);
702 void convertColor (vk::VkSamplerYcbcrModelConversionKHR colorModel,
703 vk::VkSamplerYcbcrRangeKHR range,
704 const FloatFormat& conversionFormat,
705 const UVec4& bitDepth,
706 const Interval input[4],
711 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR:
713 for (size_t ndx = 0; ndx < 4; ndx++)
714 output[ndx] = input[ndx];
718 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR:
720 output[0] = clampMaybe(rangeExpandChroma(range, conversionFormat, bitDepth[0], input[0]), -0.5, 0.5);
721 output[1] = clampMaybe(rangeExpandLuma(range, conversionFormat, bitDepth[1], input[1]), 0.0, 1.0);
722 output[2] = clampMaybe(rangeExpandChroma(range, conversionFormat, bitDepth[2], input[2]), -0.5, 0.5);
723 output[3] = input[3];
727 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR:
729 const Interval y (rangeExpandLuma(range, conversionFormat, bitDepth[1], input[1]));
730 const Interval cr (rangeExpandChroma(range, conversionFormat, bitDepth[0], input[0]));
731 const Interval cb (rangeExpandChroma(range, conversionFormat, bitDepth[2], input[2]));
733 const Interval yClamped (clampMaybe(y, 0.0, 1.0));
734 const Interval crClamped (clampMaybe(cr, -0.5, 0.5));
735 const Interval cbClamped (clampMaybe(cb, -0.5, 0.5));
737 output[0] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.402 * crClamped, false), false);
738 output[1] = conversionFormat.roundOut(conversionFormat.roundOut(yClamped - conversionFormat.roundOut((0.202008 / 0.587) * cbClamped, false), false) - conversionFormat.roundOut((0.419198 / 0.587) * crClamped, false), false);
739 output[2] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.772 * cbClamped, false), false);
740 output[3] = input[3];
744 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR:
746 const Interval y (rangeExpandLuma(range, conversionFormat, bitDepth[1], input[1]));
747 const Interval cr (rangeExpandChroma(range, conversionFormat, bitDepth[0], input[0]));
748 const Interval cb (rangeExpandChroma(range, conversionFormat, bitDepth[2], input[2]));
750 const Interval yClamped (clampMaybe(y, 0.0, 1.0));
751 const Interval crClamped (clampMaybe(cr, -0.5, 0.5));
752 const Interval cbClamped (clampMaybe(cb, -0.5, 0.5));
754 output[0] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.5748 * crClamped, false), false);
755 output[1] = conversionFormat.roundOut(conversionFormat.roundOut(yClamped - conversionFormat.roundOut((0.13397432 / 0.7152) * cbClamped, false), false) - conversionFormat.roundOut((0.33480248 / 0.7152) * crClamped, false), false);
756 output[2] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.8556 * cbClamped, false), false);
757 output[3] = input[3];
761 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR:
763 const Interval y (rangeExpandLuma(range, conversionFormat, bitDepth[1], input[1]));
764 const Interval cr (rangeExpandChroma(range, conversionFormat, bitDepth[0], input[0]));
765 const Interval cb (rangeExpandChroma(range, conversionFormat, bitDepth[2], input[2]));
767 const Interval yClamped (clampMaybe(y, 0.0, 1.0));
768 const Interval crClamped (clampMaybe(cr, -0.5, 0.5));
769 const Interval cbClamped (clampMaybe(cb, -0.5, 0.5));
771 output[0] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.4746 * crClamped, false), false);
772 output[1] = conversionFormat.roundOut(conversionFormat.roundOut(yClamped - conversionFormat.roundOut(conversionFormat.roundOut(0.11156702 / 0.6780, false) * cbClamped, false), false) - conversionFormat.roundOut(conversionFormat.roundOut(0.38737742 / 0.6780, false) * crClamped, false), false);
773 output[2] = conversionFormat.roundOut(yClamped + conversionFormat.roundOut(1.8814 * cbClamped, false), false);
774 output[3] = input[3];
779 DE_FATAL("Unknown YCbCrModel");
782 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR)
784 for (int ndx = 0; ndx < 3; ndx++)
785 output[ndx] = clampMaybe(output[ndx], 0.0, 1.0);
789 int mirror (int coord)
791 return coord >= 0 ? coord : -(1 + coord);
794 int imod (int a, int b)
797 return m < 0 ? m + b : m;
800 int wrap (vk::VkSamplerAddressMode addressMode,
806 case vk::VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
807 return (size - 1) - mirror(imod(coord, 2 * size) - size);
809 case vk::VK_SAMPLER_ADDRESS_MODE_REPEAT:
810 return imod(coord, size);
812 case vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
813 return de::clamp(coord, 0, size - 1);
815 case vk::VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
816 return de::clamp(mirror(coord), 0, size - 1);
819 DE_FATAL("Unknown wrap mode");
824 Interval frac (const Interval& x)
826 if (x.hi() - x.lo() >= 1.0)
827 return Interval(0.0, 1.0);
830 const Interval ret (deFrac(x.lo()), deFrac(x.hi()));
836 Interval calculateUV (const FloatFormat& coordFormat,
840 return coordFormat.roundOut(coordFormat.roundOut(st, false) * Interval((double)size), false);
843 IVec2 calculateNearestIJRange (const FloatFormat& coordFormat,
846 const Interval ij (coordFormat.roundOut(coordFormat.roundOut(uv, false) - Interval(0.5), false));
848 return IVec2(deRoundToInt32(ij.lo() - coordFormat.ulp(ij.lo(), 1)), deRoundToInt32(ij.hi() + coordFormat.ulp(ij.hi(), 1)));
851 // Calculate range of pixel coordinates that can be used as lower coordinate for linear sampling
852 IVec2 calculateLinearIJRange (const FloatFormat& coordFormat,
855 const Interval ij (coordFormat.roundOut(uv - Interval(0.5), false));
857 return IVec2(deFloorToInt32(ij.lo()), deFloorToInt32(ij.hi()));
860 Interval calculateAB (const deUint32 subTexelPrecisionBits,
864 const deUint32 subdivisions = 0x1u << subTexelPrecisionBits;
865 const Interval ab (frac((uv - 0.5) & Interval((double)ij, (double)(ij + 1))));
866 const Interval gridAB (ab * Interval(subdivisions));
867 const Interval rounded (de::max(deFloor(gridAB.lo()) / subdivisions, 0.0) , de::min(deCeil(gridAB.hi()) / subdivisions, 1.0));
872 Interval lookupWrapped (const ChannelAccess& access,
873 const FloatFormat& conversionFormat,
874 vk::VkSamplerAddressMode addressModeU,
875 vk::VkSamplerAddressMode addressModeV,
878 return access.getChannel(conversionFormat, IVec3(wrap(addressModeU, coord.x(), access.getSize().x()), wrap(addressModeV, coord.y(), access.getSize().y()), 0));
881 Interval linearInterpolate (const FloatFormat& filteringFormat,
889 const Interval p[4] =
896 Interval result (0.0);
898 for (size_t ndx = 0; ndx < 4; ndx++)
900 const Interval weightA (filteringFormat.roundOut((ndx % 2) == 0 ? (1.0 - a) : a, false));
901 const Interval weightB (filteringFormat.roundOut((ndx / 2) == 0 ? (1.0 - b) : b, false));
902 const Interval weight (filteringFormat.roundOut(weightA * weightB, false));
904 result = filteringFormat.roundOut(result + filteringFormat.roundOut(p[ndx] * weight, false), false);
910 Interval calculateImplicitChromaUV (const FloatFormat& coordFormat,
911 vk::VkChromaLocationKHR offset,
914 if (offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR)
915 return coordFormat.roundOut(0.5 * coordFormat.roundOut(uv + 0.5, false), false);
917 return coordFormat.roundOut(0.5 * uv, false);
920 Interval linearSample (const ChannelAccess& access,
921 const FloatFormat& conversionFormat,
922 const FloatFormat& filteringFormat,
923 vk::VkSamplerAddressMode addressModeU,
924 vk::VkSamplerAddressMode addressModeV,
929 return linearInterpolate(filteringFormat, a, b,
930 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + IVec2(0, 0)),
931 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + IVec2(1, 0)),
932 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + IVec2(0, 1)),
933 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + IVec2(1, 1)));
936 int divFloor (int a, int b)
946 Interval reconstructLinearXChromaSample (const FloatFormat& filteringFormat,
947 const FloatFormat& conversionFormat,
948 vk::VkChromaLocationKHR offset,
949 vk::VkSamplerAddressMode addressModeU,
950 vk::VkSamplerAddressMode addressModeV,
951 const ChannelAccess& access,
955 const int subI = divFloor(i, 2);
957 if (offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR)
960 return lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, j));
963 const Interval a (filteringFormat.roundOut(0.5 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, j)), false));
964 const Interval b (filteringFormat.roundOut(0.5 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI + 1, j)), false));
966 return filteringFormat.roundOut(a + b, false);
969 else if (offset == vk::VK_CHROMA_LOCATION_MIDPOINT_KHR)
973 const Interval a (filteringFormat.roundOut(0.25 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI - 1, j)), false));
974 const Interval b (filteringFormat.roundOut(0.75 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, j)), false));
976 return filteringFormat.roundOut(a + b, false);
980 const Interval a (filteringFormat.roundOut(0.25 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI + 1, j)), false));
981 const Interval b (filteringFormat.roundOut(0.75 * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, j)), false));
983 return filteringFormat.roundOut(a + b, false);
988 DE_FATAL("Unknown sample location");
993 Interval reconstructLinearXYChromaSample (const FloatFormat& filteringFormat,
994 const FloatFormat& conversionFormat,
995 vk::VkChromaLocationKHR xOffset,
996 vk::VkChromaLocationKHR yOffset,
997 vk::VkSamplerAddressMode addressModeU,
998 vk::VkSamplerAddressMode addressModeV,
999 const ChannelAccess& access,
1003 const int subI = xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR
1005 : (i % 2 == 0 ? divFloor(i, 2) - 1 : divFloor(i, 2));
1006 const int subJ = yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR
1008 : (j % 2 == 0 ? divFloor(j, 2) - 1 : divFloor(j, 2));
1010 const double a = xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR
1011 ? (i % 2 == 0 ? 0.0 : 0.5)
1012 : (i % 2 == 0 ? 0.25 : 0.75);
1013 const double b = yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR
1014 ? (j % 2 == 0 ? 0.0 : 0.5)
1015 : (j % 2 == 0 ? 0.25 : 0.75);
1017 return linearInterpolate(filteringFormat, a, b,
1018 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, subJ)),
1019 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI + 1, subJ)),
1020 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI, subJ + 1)),
1021 lookupWrapped(access, conversionFormat, addressModeU, addressModeV, IVec2(subI + 1, subJ + 1)));
1024 const ChannelAccess& swizzle (vk::VkComponentSwizzle swizzle,
1025 const ChannelAccess& identityPlane,
1026 const ChannelAccess& rPlane,
1027 const ChannelAccess& gPlane,
1028 const ChannelAccess& bPlane,
1029 const ChannelAccess& aPlane)
1033 case vk::VK_COMPONENT_SWIZZLE_IDENTITY: return identityPlane;
1034 case vk::VK_COMPONENT_SWIZZLE_R: return rPlane;
1035 case vk::VK_COMPONENT_SWIZZLE_G: return gPlane;
1036 case vk::VK_COMPONENT_SWIZZLE_B: return bPlane;
1037 case vk::VK_COMPONENT_SWIZZLE_A: return aPlane;
1040 DE_FATAL("Unsupported swizzle");
1041 return identityPlane;
1045 void calculateBounds (const ChannelAccess& rPlane,
1046 const ChannelAccess& gPlane,
1047 const ChannelAccess& bPlane,
1048 const ChannelAccess& aPlane,
1049 const UVec4& bitDepth,
1050 const vector<Vec2>& sts,
1051 const FloatFormat& filteringFormat,
1052 const FloatFormat& conversionFormat,
1053 const deUint32 subTexelPrecisionBits,
1054 vk::VkFilter filter,
1055 vk::VkSamplerYcbcrModelConversionKHR colorModel,
1056 vk::VkSamplerYcbcrRangeKHR range,
1057 vk::VkFilter chromaFilter,
1058 vk::VkChromaLocationKHR xChromaOffset,
1059 vk::VkChromaLocationKHR yChromaOffset,
1060 const vk::VkComponentMapping& componentMapping,
1061 bool explicitReconstruction,
1062 vk::VkSamplerAddressMode addressModeU,
1063 vk::VkSamplerAddressMode addressModeV,
1064 std::vector<Vec4>& minBounds,
1065 std::vector<Vec4>& maxBounds,
1066 std::vector<Vec4>& uvBounds,
1067 std::vector<IVec4>& ijBounds)
1069 const FloatFormat highp (-126, 127, 23, true,
1070 tcu::MAYBE, // subnormals
1071 tcu::YES, // infinities
1073 const FloatFormat coordFormat (-32, 32, 16, true);
1074 const ChannelAccess& rAccess (swizzle(componentMapping.r, rPlane, rPlane, gPlane, bPlane, aPlane));
1075 const ChannelAccess& gAccess (swizzle(componentMapping.g, gPlane, rPlane, gPlane, bPlane, aPlane));
1076 const ChannelAccess& bAccess (swizzle(componentMapping.b, bPlane, rPlane, gPlane, bPlane, aPlane));
1077 const ChannelAccess& aAccess (swizzle(componentMapping.a, aPlane, rPlane, gPlane, bPlane, aPlane));
1079 const bool subsampledX = gAccess.getSize().x() > rAccess.getSize().x();
1080 const bool subsampledY = gAccess.getSize().y() > rAccess.getSize().y();
1082 minBounds.resize(sts.size(), Vec4(TCU_INFINITY));
1083 maxBounds.resize(sts.size(), Vec4(-TCU_INFINITY));
1085 uvBounds.resize(sts.size(), Vec4(TCU_INFINITY, -TCU_INFINITY, TCU_INFINITY, -TCU_INFINITY));
1086 ijBounds.resize(sts.size(), IVec4(0x7FFFFFFF, -1 -0x7FFFFFFF, 0x7FFFFFFF, -1 -0x7FFFFFFF));
1088 // Chroma plane sizes must match
1089 DE_ASSERT(rAccess.getSize() == bAccess.getSize());
1091 // Luma plane sizes must match
1092 DE_ASSERT(gAccess.getSize() == aAccess.getSize());
1094 // Luma plane size must match chroma plane or be twice as big
1095 DE_ASSERT(rAccess.getSize().x() == gAccess.getSize().x() || 2 * rAccess.getSize().x() == gAccess.getSize().x());
1096 DE_ASSERT(rAccess.getSize().y() == gAccess.getSize().y() || 2 * rAccess.getSize().y() == gAccess.getSize().y());
1098 for (size_t ndx = 0; ndx < sts.size(); ndx++)
1100 const Vec2 st (sts[ndx]);
1103 const Interval u (calculateUV(coordFormat, st[0], gAccess.getSize().x()));
1104 const Interval v (calculateUV(coordFormat, st[1], gAccess.getSize().y()));
1106 uvBounds[ndx][0] = (float)u.lo();
1107 uvBounds[ndx][1] = (float)u.hi();
1109 uvBounds[ndx][2] = (float)v.lo();
1110 uvBounds[ndx][3] = (float)v.hi();
1112 if (filter == vk::VK_FILTER_NEAREST)
1114 const IVec2 iRange (calculateNearestIJRange(coordFormat, u));
1115 const IVec2 jRange (calculateNearestIJRange(coordFormat, v));
1117 ijBounds[ndx][0] = iRange[0];
1118 ijBounds[ndx][1] = iRange[1];
1120 ijBounds[ndx][2] = jRange[0];
1121 ijBounds[ndx][3] = jRange[1];
1123 for (int j = jRange.x(); j <= jRange.y(); j++)
1124 for (int i = iRange.x(); i <= iRange.y(); i++)
1126 const Interval gValue (lookupWrapped(gAccess, conversionFormat, addressModeU, addressModeV, IVec2(i, j)));
1127 const Interval aValue (lookupWrapped(aAccess, conversionFormat, addressModeU, addressModeV, IVec2(i, j)));
1129 if (subsampledX || subsampledY)
1131 if (explicitReconstruction)
1133 if (chromaFilter == vk::VK_FILTER_NEAREST)
1135 // Nearest, Reconstructed chroma with explicit nearest filtering
1136 const int subI = subsampledX ? i / 2 : i;
1137 const int subJ = subsampledY ? j / 2 : j;
1138 const Interval srcColor[] =
1140 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(subI, subJ)),
1142 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(subI, subJ)),
1145 Interval dstColor[4];
1147 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1149 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1150 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1152 else if (chromaFilter == vk::VK_FILTER_LINEAR)
1154 if (subsampledX && subsampledY)
1156 // Nearest, Reconstructed both chroma samples with explicit linear filtering
1157 const Interval rValue (reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j));
1158 const Interval bValue (reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j));
1159 const Interval srcColor[] =
1166 Interval dstColor[4];
1168 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1170 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1171 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1173 else if (subsampledX)
1175 // Nearest, Reconstructed x chroma samples with explicit linear filtering
1176 const Interval rValue (reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, rAccess, i, j));
1177 const Interval bValue (reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, bAccess, i, j));
1178 const Interval srcColor[] =
1185 Interval dstColor[4];
1187 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1189 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1190 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1193 DE_FATAL("Unexpected chroma reconstruction");
1196 DE_FATAL("Unknown filter");
1200 const Interval chromaU (subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u);
1201 const Interval chromaV (subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v);
1203 if (chromaFilter == vk::VK_FILTER_NEAREST)
1205 // Nearest, reconstructed chroma samples with implicit nearest filtering
1206 const IVec2 chromaIRange (subsampledX ? calculateNearestIJRange(coordFormat, chromaU) : IVec2(i, i));
1207 const IVec2 chromaJRange (subsampledY ? calculateNearestIJRange(coordFormat, chromaV) : IVec2(j, j));
1209 for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
1210 for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.x(); chromaI++)
1212 const Interval srcColor[] =
1214 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ)),
1216 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ)),
1219 Interval dstColor[4];
1221 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1223 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1224 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1227 else if (chromaFilter == vk::VK_FILTER_LINEAR)
1229 // Nearest, reconstructed chroma samples with implicit linear filtering
1230 const IVec2 chromaIRange (subsampledX ? calculateLinearIJRange(coordFormat, chromaU) : IVec2(i, i));
1231 const IVec2 chromaJRange (subsampledY ? calculateLinearIJRange(coordFormat, chromaV) : IVec2(j, j));
1233 for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
1234 for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.x(); chromaI++)
1236 const Interval chromaA (calculateAB(subTexelPrecisionBits, chromaU, chromaI));
1237 const Interval chromaB (calculateAB(subTexelPrecisionBits, chromaV, chromaJ));
1239 const Interval srcColor[] =
1241 linearSample(rAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB),
1243 linearSample(bAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB),
1246 Interval dstColor[4];
1248 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1250 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1251 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1255 DE_FATAL("Unknown filter");
1260 // Linear, no chroma subsampling
1261 const Interval srcColor[] =
1263 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(i, j)),
1265 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(i, j)),
1268 Interval dstColor[4];
1270 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1272 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1273 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1277 else if (filter == vk::VK_FILTER_LINEAR)
1279 const IVec2 iRange (calculateLinearIJRange(coordFormat, u));
1280 const IVec2 jRange (calculateLinearIJRange(coordFormat, v));
1282 ijBounds[ndx][0] = iRange[0];
1283 ijBounds[ndx][1] = iRange[1];
1285 ijBounds[ndx][2] = jRange[0];
1286 ijBounds[ndx][3] = jRange[1];
1288 for (int j = jRange.x(); j <= jRange.y(); j++)
1289 for (int i = iRange.x(); i <= iRange.y(); i++)
1291 const Interval lumaA (calculateAB(subTexelPrecisionBits, u, i));
1292 const Interval lumaB (calculateAB(subTexelPrecisionBits, v, j));
1294 const Interval gValue (linearSample(gAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB));
1295 const Interval aValue (linearSample(aAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB));
1297 if (subsampledX || subsampledY)
1299 if (explicitReconstruction)
1301 if (chromaFilter == vk::VK_FILTER_NEAREST)
1303 const Interval srcColor[] =
1305 linearInterpolate(filteringFormat, lumaA, lumaB,
1306 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))),
1307 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))),
1308 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))),
1309 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1)))),
1311 linearInterpolate(filteringFormat, lumaA, lumaB,
1312 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))),
1313 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))),
1314 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))),
1315 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1)))),
1318 Interval dstColor[4];
1320 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1322 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1323 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1325 else if (chromaFilter == vk::VK_FILTER_LINEAR)
1327 if (subsampledX && subsampledY)
1329 // Linear, Reconstructed xx chroma samples with explicit linear filtering
1330 const Interval rValue (linearInterpolate(filteringFormat, lumaA, lumaB,
1331 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j),
1332 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j),
1333 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1),
1334 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1)));
1335 const Interval bValue (linearInterpolate(filteringFormat, lumaA, lumaB,
1336 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j),
1337 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j),
1338 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1),
1339 reconstructLinearXYChromaSample(filteringFormat, conversionFormat, xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1)));
1340 const Interval srcColor[] =
1347 Interval dstColor[4];
1349 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1351 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1352 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1355 else if (subsampledX)
1357 // Linear, Reconstructed x chroma samples with explicit linear filtering
1358 const Interval rValue (linearInterpolate(filteringFormat, lumaA, lumaB,
1359 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, rAccess, i, j),
1360 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j),
1361 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1),
1362 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1)));
1363 const Interval bValue (linearInterpolate(filteringFormat, lumaA, lumaB,
1364 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, bAccess, i, j),
1365 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j),
1366 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1),
1367 reconstructLinearXChromaSample(filteringFormat, conversionFormat, xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1)));
1368 const Interval srcColor[] =
1375 Interval dstColor[4];
1377 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1379 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1380 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1383 DE_FATAL("Unknown subsampling config");
1386 DE_FATAL("Unknown chroma filter");
1390 const Interval chromaU (subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u);
1391 const Interval chromaV (subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v);
1393 if (chromaFilter == vk::VK_FILTER_NEAREST)
1395 const IVec2 chromaIRange (calculateNearestIJRange(coordFormat, chromaU));
1396 const IVec2 chromaJRange (calculateNearestIJRange(coordFormat, chromaV));
1398 for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
1399 for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.x(); chromaI++)
1401 const Interval srcColor[] =
1403 lookupWrapped(rAccess, conversionFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ)),
1405 lookupWrapped(bAccess, conversionFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ)),
1408 Interval dstColor[4];
1410 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1412 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1413 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1416 else if (chromaFilter == vk::VK_FILTER_LINEAR)
1418 const IVec2 chromaIRange (calculateNearestIJRange(coordFormat, chromaU));
1419 const IVec2 chromaJRange (calculateNearestIJRange(coordFormat, chromaV));
1421 for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++)
1422 for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.x(); chromaI++)
1424 const Interval chromaA (calculateAB(subTexelPrecisionBits, chromaU, chromaI));
1425 const Interval chromaB (calculateAB(subTexelPrecisionBits, chromaV, chromaJ));
1427 const Interval rValue (linearSample(rAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB));
1428 const Interval bValue (linearSample(bAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB));
1430 const Interval srcColor[] =
1437 Interval dstColor[4];
1438 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1440 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1441 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1445 DE_FATAL("Unknown chroma filter");
1450 const Interval chromaA (lumaA);
1451 const Interval chromaB (lumaB);
1452 const Interval rValue (linearSample(rAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(i, j), chromaA, chromaB));
1453 const Interval bValue (linearSample(bAccess, conversionFormat, filteringFormat, addressModeU, addressModeV, IVec2(i, j), chromaA, chromaB));
1454 const Interval srcColor[] =
1461 Interval dstColor[4];
1463 convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor);
1465 for (size_t compNdx = 0; compNdx < 4; compNdx++)
1466 bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false);
1471 DE_FATAL("Unknown filter");
1473 minBounds[ndx] = Vec4((float)bounds[0].lo(), (float)bounds[1].lo(), (float)bounds[2].lo(), (float)bounds[3].lo());
1474 maxBounds[ndx] = Vec4((float)bounds[0].hi(), (float)bounds[1].hi(), (float)bounds[2].hi(), (float)bounds[3].hi());
1480 TestConfig (glu::ShaderType shaderType_,
1481 vk::VkFormat format_,
1482 vk::VkImageTiling imageTiling_,
1483 vk::VkFilter textureFilter_,
1484 vk::VkSamplerAddressMode addressModeU_,
1485 vk::VkSamplerAddressMode addressModeV_,
1487 vk::VkFilter chromaFilter_,
1488 vk::VkChromaLocationKHR xChromaOffset_,
1489 vk::VkChromaLocationKHR yChromaOffset_,
1490 bool explicitReconstruction_,
1493 vk::VkSamplerYcbcrRangeKHR colorRange_,
1494 vk::VkSamplerYcbcrModelConversionKHR colorModel_,
1495 vk::VkComponentMapping componentMapping_)
1496 : shaderType (shaderType_)
1498 , imageTiling (imageTiling_)
1499 , textureFilter (textureFilter_)
1500 , addressModeU (addressModeU_)
1501 , addressModeV (addressModeV_)
1503 , chromaFilter (chromaFilter_)
1504 , xChromaOffset (xChromaOffset_)
1505 , yChromaOffset (yChromaOffset_)
1506 , explicitReconstruction (explicitReconstruction_)
1507 , disjoint (disjoint_)
1509 , colorRange (colorRange_)
1510 , colorModel (colorModel_)
1511 , componentMapping (componentMapping_)
1515 glu::ShaderType shaderType;
1516 vk::VkFormat format;
1517 vk::VkImageTiling imageTiling;
1518 vk::VkFilter textureFilter;
1519 vk::VkSamplerAddressMode addressModeU;
1520 vk::VkSamplerAddressMode addressModeV;
1522 vk::VkFilter chromaFilter;
1523 vk::VkChromaLocationKHR xChromaOffset;
1524 vk::VkChromaLocationKHR yChromaOffset;
1525 bool explicitReconstruction;
1528 vk::VkSamplerYcbcrRangeKHR colorRange;
1529 vk::VkSamplerYcbcrModelConversionKHR colorModel;
1530 vk::VkComponentMapping componentMapping;
1533 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vkd,
1534 vk::VkDevice device,
1535 vk::VkSampler sampler)
1537 const vk::VkDescriptorSetLayoutBinding layoutBindings[] =
1541 vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1543 vk::VK_SHADER_STAGE_ALL,
1547 const vk::VkDescriptorSetLayoutCreateInfo layoutCreateInfo =
1549 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1553 DE_LENGTH_OF_ARRAY(layoutBindings),
1557 return vk::createDescriptorSetLayout(vkd, device, &layoutCreateInfo);
1560 vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vkd,
1561 vk::VkDevice device)
1563 const vk::VkDescriptorPoolSize poolSizes[] =
1565 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, }
1567 const vk::VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
1569 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1571 vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1574 DE_LENGTH_OF_ARRAY(poolSizes),
1578 return createDescriptorPool(vkd, device, &descriptorPoolCreateInfo);
1581 vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vkd,
1582 vk::VkDevice device,
1583 vk::VkDescriptorPool descriptorPool,
1584 vk::VkDescriptorSetLayout layout,
1585 vk::VkSampler sampler,
1586 vk::VkImageView imageView)
1588 const vk::VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
1590 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1597 vk::Move<vk::VkDescriptorSet> descriptorSet (vk::allocateDescriptorSet(vkd, device, &descriptorSetAllocateInfo));
1598 const vk::VkDescriptorImageInfo imageInfo =
1602 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
1606 const vk::VkWriteDescriptorSet writes[] =
1609 vk::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
1616 vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
1623 vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(writes), writes, 0u, DE_NULL);
1626 return descriptorSet;
1629 vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vkd,
1630 vk::VkDevice device,
1631 vk::VkFilter textureFilter,
1632 vk::VkSamplerAddressMode addressModeU,
1633 vk::VkSamplerAddressMode addressModeV,
1634 vk::VkSamplerYcbcrConversionKHR conversion)
1636 #if !defined(FAKE_COLOR_CONVERSION)
1637 const vk::VkSamplerYcbcrConversionInfoKHR samplerConversionInfo =
1639 vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR,
1644 DE_UNREF(conversion);
1646 const vk::VkSamplerCreateInfo createInfo =
1648 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
1649 #if !defined(FAKE_COLOR_CONVERSION)
1650 &samplerConversionInfo,
1658 vk::VK_SAMPLER_MIPMAP_MODE_NEAREST,
1661 vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
1666 vk::VK_COMPARE_OP_ALWAYS,
1669 vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
1673 return createSampler(vkd, device, &createInfo);
1676 vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vkd,
1677 vk::VkDevice device,
1678 vk::VkFormat format,
1681 vk::VkImageTiling tiling)
1683 const vk::VkImageCreateInfo createInfo =
1685 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
1687 disjoint ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (vk::VkImageCreateFlags)0u,
1689 vk::VK_IMAGE_TYPE_2D,
1691 vk::makeExtent3D(size.x(), size.y(), 1u),
1694 vk::VK_SAMPLE_COUNT_1_BIT,
1696 vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT | vk::VK_IMAGE_USAGE_SAMPLED_BIT,
1697 vk::VK_SHARING_MODE_EXCLUSIVE,
1699 (const deUint32*)DE_NULL,
1700 vk::VK_IMAGE_LAYOUT_UNDEFINED,
1703 return vk::createImage(vkd, device, &createInfo);
1706 vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vkd,
1707 vk::VkDevice device,
1709 vk::VkFormat format,
1710 vk::VkSamplerYcbcrConversionKHR conversion)
1712 #if !defined(FAKE_COLOR_CONVERSION)
1713 const vk::VkSamplerYcbcrConversionInfoKHR conversionInfo =
1715 vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR,
1720 DE_UNREF(conversion);
1722 const vk::VkImageViewCreateInfo viewInfo =
1724 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
1725 #if defined(FAKE_COLOR_CONVERSION)
1730 (vk::VkImageViewCreateFlags)0,
1733 vk::VK_IMAGE_VIEW_TYPE_2D,
1736 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1737 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1738 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1739 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
1741 { vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },
1744 return vk::createImageView(vkd, device, &viewInfo);
1747 vk::Move<vk::VkSamplerYcbcrConversionKHR> createConversion (const vk::DeviceInterface& vkd,
1748 vk::VkDevice device,
1749 vk::VkFormat format,
1750 vk::VkSamplerYcbcrModelConversionKHR colorModel,
1751 vk::VkSamplerYcbcrRangeKHR colorRange,
1752 vk::VkChromaLocationKHR xChromaOffset,
1753 vk::VkChromaLocationKHR yChromaOffset,
1754 vk::VkFilter chromaFilter,
1755 const vk::VkComponentMapping& componentMapping,
1756 bool explicitReconstruction)
1758 const vk::VkSamplerYcbcrConversionCreateInfoKHR conversionInfo =
1760 vk::VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR,
1770 explicitReconstruction ? VK_TRUE : VK_FALSE
1773 return vk::createSamplerYcbcrConversionKHR(vkd, device, &conversionInfo);
1776 void evalShader (Context& context,
1777 glu::ShaderType shaderType,
1778 const MultiPlaneImageData& imageData,
1780 vk::VkFormat format,
1781 vk::VkImageTiling imageTiling,
1783 vk::VkFilter textureFilter,
1784 vk::VkSamplerAddressMode addressModeU,
1785 vk::VkSamplerAddressMode addressModeV,
1786 vk::VkSamplerYcbcrModelConversionKHR colorModel,
1787 vk::VkSamplerYcbcrRangeKHR colorRange,
1788 vk::VkChromaLocationKHR xChromaOffset,
1789 vk::VkChromaLocationKHR yChromaOffset,
1790 vk::VkFilter chromaFilter,
1791 const vk::VkComponentMapping& componentMapping,
1792 bool explicitReconstruction,
1793 const vector<Vec2>& sts,
1794 vector<Vec4>& results)
1796 const vk::DeviceInterface& vkd (context.getDeviceInterface());
1797 const vk::VkDevice device (context.getDevice());
1798 #if !defined(FAKE_COLOR_CONVERSION)
1799 const vk::Unique<vk::VkSamplerYcbcrConversionKHR> conversion (createConversion(vkd, device, format, colorModel, colorRange, xChromaOffset, yChromaOffset, chromaFilter, componentMapping, explicitReconstruction));
1800 const vk::Unique<vk::VkSampler> sampler (createSampler(vkd, device, textureFilter, addressModeU, addressModeV, *conversion));
1802 DE_UNREF(colorModel);
1803 DE_UNREF(colorRange);
1804 DE_UNREF(xChromaOffset);
1805 DE_UNREF(yChromaOffset);
1806 DE_UNREF(chromaFilter);
1807 DE_UNREF(explicitReconstruction);
1808 DE_UNREF(componentMapping);
1809 DE_UNREF(createConversion);
1810 const vk::Unique<vk::VkSampler> sampler (createSampler(vkd, device, textureFilter, addressModeU, addressModeV, (vk::VkSamplerYcbcrConversionKHR)0u));
1812 const vk::Unique<vk::VkImage> image (createImage(vkd, device, format, size, disjoint, imageTiling));
1813 const vk::MemoryRequirement memoryRequirement (imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
1814 ? vk::MemoryRequirement::Any
1815 : vk::MemoryRequirement::HostVisible);
1816 const vk::VkImageCreateFlags createFlags (disjoint ? vk::VK_IMAGE_CREATE_DISJOINT_BIT_KHR : (vk::VkImageCreateFlagBits)0u);
1817 const vector<AllocationSp> imageMemory (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags, memoryRequirement));
1818 #if defined(FAKE_COLOR_CONVERSION)
1819 const vk::Unique<vk::VkImageView> imageView (createImageView(vkd, device, *image, format, (vk::VkSamplerYcbcrConversionKHR)0));
1821 const vk::Unique<vk::VkImageView> imageView (createImageView(vkd, device, *image, format, *conversion));
1824 const vk::Unique<vk::VkDescriptorSetLayout> layout (createDescriptorSetLayout(vkd, device, *sampler));
1825 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool(vkd, device));
1826 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(vkd, device, *descriptorPool, *layout, *sampler, *imageView));
1828 const ShaderSpec spec (createShaderSpec());
1829 const de::UniquePtr<ShaderExecutor> executor (createExecutor(context, shaderType, spec, *layout));
1831 if (imageTiling == vk::VK_IMAGE_TILING_OPTIMAL)
1832 uploadImage(vkd, device, context.getUniversalQueueFamilyIndex(), context.getDefaultAllocator(), *image, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1834 fillImageMemory(vkd, device, context.getUniversalQueueFamilyIndex(), *image, imageMemory, imageData, vk::VK_ACCESS_SHADER_READ_BIT, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1836 results.resize(sts.size());
1839 const void* const inputs[] =
1843 void* const outputs[] =
1848 executor->execute((int)sts.size(), inputs, outputs, *descriptorSet);
1852 bool isXChromaSubsampled (vk::VkFormat format)
1856 case vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
1857 case vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
1858 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
1859 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
1860 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
1861 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
1862 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
1863 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
1864 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
1865 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
1866 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
1867 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
1868 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
1869 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
1870 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
1871 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
1872 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
1873 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
1874 case vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
1875 case vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
1876 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
1877 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
1878 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
1879 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
1887 bool isYChromaSubsampled (vk::VkFormat format)
1891 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
1892 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
1893 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
1894 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
1895 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
1896 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
1897 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
1898 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
1906 void logTestCaseInfo (TestLog& log, const TestConfig& config)
1908 log << TestLog::Message << "ShaderType: " << config.shaderType << TestLog::EndMessage;
1909 log << TestLog::Message << "Format: " << config.format << TestLog::EndMessage;
1910 log << TestLog::Message << "ImageTiling: " << config.imageTiling << TestLog::EndMessage;
1911 log << TestLog::Message << "TextureFilter: " << config.textureFilter << TestLog::EndMessage;
1912 log << TestLog::Message << "AddressModeU: " << config.addressModeU << TestLog::EndMessage;
1913 log << TestLog::Message << "AddressModeV: " << config.addressModeV << TestLog::EndMessage;
1914 log << TestLog::Message << "ChromaFilter: " << config.chromaFilter << TestLog::EndMessage;
1915 log << TestLog::Message << "XChromaOffset: " << config.xChromaOffset << TestLog::EndMessage;
1916 log << TestLog::Message << "YChromaOffset: " << config.yChromaOffset << TestLog::EndMessage;
1917 log << TestLog::Message << "ExplicitReconstruction: " << (config.explicitReconstruction ? "true" : "false") << TestLog::EndMessage;
1918 log << TestLog::Message << "Disjoint: " << (config.explicitReconstruction ? "true" : "false") << TestLog::EndMessage;
1919 log << TestLog::Message << "ColorRange: " << config.colorRange << TestLog::EndMessage;
1920 log << TestLog::Message << "ColorModel: " << config.colorModel << TestLog::EndMessage;
1921 log << TestLog::Message << "ComponentMapping: " << config.componentMapping << TestLog::EndMessage;
1925 tcu::TestStatus textureConversionTest (Context& context, const TestConfig config)
1927 const FloatFormat filteringPrecision (getFilteringPrecision(config.format));
1928 const FloatFormat conversionPrecision (getConversionPrecision(config.format));
1929 const deUint32 subTexelPrecisionBits (vk::getPhysicalDeviceProperties(context.getInstanceInterface(), context.getPhysicalDevice()).limits.subTexelPrecisionBits);
1930 const tcu::UVec4 bitDepth (getBitDepth(config.format));
1931 const UVec2 size (isXChromaSubsampled(config.format) ? 12 : 7,
1932 isYChromaSubsampled(config.format) ? 8 : 13);
1933 TestLog& log (context.getTestContext().getLog());
1934 bool explicitReconstruction = config.explicitReconstruction;
1937 logTestCaseInfo(log, config);
1939 #if !defined(FAKE_COLOR_CONVERSION)
1940 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), string("VK_KHR_sampler_ycbcr_conversion")))
1941 TCU_THROW(NotSupportedError, "Extension VK_KHR_sampler_ycbcr_conversion not supported");
1945 const vk::VkFormatProperties properties (vk::getPhysicalDeviceFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), config.format));
1946 const vk::VkFormatFeatureFlags features (config.imageTiling == vk::VK_IMAGE_TILING_OPTIMAL
1947 ? properties.optimalTilingFeatures
1948 : properties.linearTilingFeatures);
1950 if ((features & (vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR | vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR)) == 0)
1951 TCU_THROW(NotSupportedError, "Format doesn't support YCbCr conversions");
1953 if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
1954 TCU_THROW(NotSupportedError, "Format doesn't support sampling");
1956 if (config.textureFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR) == 0))
1957 TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");
1959 if (config.chromaFilter == vk::VK_FILTER_LINEAR && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR) == 0))
1960 TCU_THROW(NotSupportedError, "Format doesn't support YCbCr linear chroma reconstruction");
1962 if (config.chromaFilter != config.textureFilter && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR) == 0))
1963 TCU_THROW(NotSupportedError, "Format doesn't support different chroma and texture filters");
1965 if (config.explicitReconstruction && ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT_KHR) == 0))
1966 TCU_THROW(NotSupportedError, "Format doesn't support explicit chroma reconstruction");
1968 if (config.disjoint && ((features & vk::VK_FORMAT_FEATURE_DISJOINT_BIT_KHR) == 0))
1969 TCU_THROW(NotSupportedError, "Format doesn't disjoint planes");
1971 if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR) == 0))
1972 TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
1974 if (isXChromaSubsampled(config.format) && (config.xChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT_KHR) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR) == 0))
1975 TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
1977 if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR) && ((features & vk::VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR) == 0))
1978 TCU_THROW(NotSupportedError, "Format doesn't support cosited chroma samples");
1980 if (isYChromaSubsampled(config.format) && (config.yChromaOffset == vk::VK_CHROMA_LOCATION_MIDPOINT_KHR) && ((features & vk::VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR) == 0))
1981 TCU_THROW(NotSupportedError, "Format doesn't support midpoint chroma samples");
1983 if ((features & vk::VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT_KHR) != 0)
1984 explicitReconstruction = true;
1986 log << TestLog::Message << "FormatFeatures: " << vk::getFormatFeatureFlagsStr(features) << TestLog::EndMessage;
1988 catch (const vk::Error& err)
1990 if (err.getError() == vk::VK_ERROR_FORMAT_NOT_SUPPORTED)
1991 TCU_THROW(NotSupportedError, "Format not supported");
1998 const vk::PlanarFormatDescription planeInfo (vk::getPlanarFormatDescription(config.format));
1999 MultiPlaneImageData src (config.format, size);
2001 deUint32 nullAccessData (0u);
2002 ChannelAccess nullAccess (tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(size.x(), size.y(), 1), IVec3(0, 0, 0), &nullAccessData, 0u);
2003 deUint32 nullAccessAlphaData (~0u);
2004 ChannelAccess nullAccessAlpha (tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, 1u, IVec3(size.x(), size.y(), 1), IVec3(0, 0, 0), &nullAccessAlphaData, 0u);
2005 ChannelAccess rChannelAccess (planeInfo.hasChannelNdx(0) ? getChannelAccess(src, planeInfo, size, 0) : nullAccess);
2006 ChannelAccess gChannelAccess (planeInfo.hasChannelNdx(1) ? getChannelAccess(src, planeInfo, size, 1) : nullAccess);
2007 ChannelAccess bChannelAccess (planeInfo.hasChannelNdx(2) ? getChannelAccess(src, planeInfo, size, 2) : nullAccess);
2008 ChannelAccess aChannelAccess (planeInfo.hasChannelNdx(3) ? getChannelAccess(src, planeInfo, size, 3) : nullAccessAlpha);
2011 vector<Vec4> results;
2012 vector<Vec4> minBounds;
2013 vector<Vec4> maxBounds;
2014 vector<Vec4> uvBounds;
2015 vector<IVec4> ijBounds;
2017 for (deUint32 planeNdx = 0; planeNdx < planeInfo.numPlanes; planeNdx++)
2018 deMemset(src.getPlanePtr(planeNdx), 0u, src.getPlaneSize(planeNdx));
2020 // \todo Limit values to only values that produce defined values using selected colorRange and colorModel? The verification code handles those cases already correctly.
2021 if (planeInfo.hasChannelNdx(0))
2023 for (int y = 0; y < rChannelAccess.getSize().y(); y++)
2024 for (int x = 0; x < rChannelAccess.getSize().x(); x++)
2025 rChannelAccess.setChannel(IVec3(x, y, 0), (float)x / (float)rChannelAccess.getSize().x());
2028 if (planeInfo.hasChannelNdx(1))
2030 for (int y = 0; y < gChannelAccess.getSize().y(); y++)
2031 for (int x = 0; x < gChannelAccess.getSize().x(); x++)
2032 gChannelAccess.setChannel(IVec3(x, y, 0), (float)y / (float)gChannelAccess.getSize().y());
2035 if (planeInfo.hasChannelNdx(2))
2037 for (int y = 0; y < bChannelAccess.getSize().y(); y++)
2038 for (int x = 0; x < bChannelAccess.getSize().x(); x++)
2039 bChannelAccess.setChannel(IVec3(x, y, 0), (float)(x + y) / (float)(bChannelAccess.getSize().x() + bChannelAccess.getSize().y()));
2042 if (planeInfo.hasChannelNdx(3))
2044 for (int y = 0; y < aChannelAccess.getSize().y(); y++)
2045 for (int x = 0; x < aChannelAccess.getSize().x(); x++)
2046 aChannelAccess.setChannel(IVec3(x, y, 0), (float)(x * y) / (float)(aChannelAccess.getSize().x() * aChannelAccess.getSize().y()));
2049 genTexCoords(sts, size);
2051 calculateBounds(rChannelAccess, gChannelAccess, bChannelAccess, aChannelAccess, bitDepth, sts, filteringPrecision, conversionPrecision, subTexelPrecisionBits, config.textureFilter, config.colorModel, config.colorRange, config.chromaFilter, config.xChromaOffset, config.yChromaOffset, config.componentMapping, explicitReconstruction, config.addressModeU, config.addressModeV, minBounds, maxBounds, uvBounds, ijBounds);
2053 if (vk::isYCbCrFormat(config.format))
2055 tcu::TextureLevel rImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), rChannelAccess.getSize().x(), rChannelAccess.getSize().y());
2056 tcu::TextureLevel gImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), gChannelAccess.getSize().x(), gChannelAccess.getSize().y());
2057 tcu::TextureLevel bImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), bChannelAccess.getSize().x(), bChannelAccess.getSize().y());
2058 tcu::TextureLevel aImage (tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::FLOAT), aChannelAccess.getSize().x(), aChannelAccess.getSize().y());
2060 for (int y = 0; y < (int)rChannelAccess.getSize().y(); y++)
2061 for (int x = 0; x < (int)rChannelAccess.getSize().x(); x++)
2062 rImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
2064 for (int y = 0; y < (int)gChannelAccess.getSize().y(); y++)
2065 for (int x = 0; x < (int)gChannelAccess.getSize().x(); x++)
2066 gImage.getAccess().setPixel(Vec4(gChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
2068 for (int y = 0; y < (int)bChannelAccess.getSize().y(); y++)
2069 for (int x = 0; x < (int)bChannelAccess.getSize().x(); x++)
2070 bImage.getAccess().setPixel(Vec4(bChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
2072 for (int y = 0; y < (int)aChannelAccess.getSize().y(); y++)
2073 for (int x = 0; x < (int)aChannelAccess.getSize().x(); x++)
2074 aImage.getAccess().setPixel(Vec4(aChannelAccess.getChannel(IVec3(x, y, 0))), x, y);
2077 const Vec4 scale (1.0f);
2078 const Vec4 bias (0.0f);
2080 log << TestLog::Image("SourceImageR", "SourceImageR", rImage.getAccess(), scale, bias);
2081 log << TestLog::Image("SourceImageG", "SourceImageG", gImage.getAccess(), scale, bias);
2082 log << TestLog::Image("SourceImageB", "SourceImageB", bImage.getAccess(), scale, bias);
2083 log << TestLog::Image("SourceImageA", "SourceImageA", aImage.getAccess(), scale, bias);
2088 tcu::TextureLevel srcImage (vk::mapVkFormat(config.format), size.x(), size.y());
2090 for (int y = 0; y < (int)size.y(); y++)
2091 for (int x = 0; x < (int)size.x(); x++)
2093 const IVec3 pos (x, y, 0);
2094 srcImage.getAccess().setPixel(Vec4(rChannelAccess.getChannel(pos), gChannelAccess.getChannel(pos), bChannelAccess.getChannel(pos), aChannelAccess.getChannel(pos)), x, y);
2097 log << TestLog::Image("SourceImage", "SourceImage", srcImage.getAccess());
2100 evalShader(context, config.shaderType, src, size, config.format, config.imageTiling, config.disjoint, config.textureFilter, config.addressModeU, config.addressModeV, config.colorModel, config.colorRange, config.xChromaOffset, config.yChromaOffset, config.chromaFilter, config.componentMapping, config.explicitReconstruction, sts, results);
2103 tcu::TextureLevel minImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), size.x() + (size.x() / 2), size.y() + (size.y() / 2));
2104 tcu::TextureLevel maxImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), size.x() + (size.x() / 2), size.y() + (size.y() / 2));
2105 tcu::TextureLevel resImage (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), size.x() + (size.x() / 2), size.y() + (size.y() / 2));
2107 for (int y = 0; y < (int)(size.y() + (size.y() / 2)); y++)
2108 for (int x = 0; x < (int)(size.x() + (size.x() / 2)); x++)
2110 const int ndx = x + y * (int)(size.x() + (size.x() / 2));
2111 minImage.getAccess().setPixel(minBounds[ndx], x, y);
2112 maxImage.getAccess().setPixel(maxBounds[ndx], x, y);
2115 for (int y = 0; y < (int)(size.y() + (size.y() / 2)); y++)
2116 for (int x = 0; x < (int)(size.x() + (size.x() / 2)); x++)
2118 const int ndx = x + y * (int)(size.x() + (size.x() / 2));
2119 resImage.getAccess().setPixel(results[ndx], x, y);
2123 const Vec4 scale (1.0f);
2124 const Vec4 bias (0.0f);
2126 log << TestLog::Image("MinBoundImage", "MinBoundImage", minImage.getAccess(), scale, bias);
2127 log << TestLog::Image("MaxBoundImage", "MaxBoundImage", maxImage.getAccess(), scale, bias);
2128 log << TestLog::Image("ResultImage", "ResultImage", resImage.getAccess(), scale, bias);
2132 size_t errorCount = 0;
2134 for (size_t ndx = 0; ndx < sts.size(); ndx++)
2136 if (tcu::boolAny(tcu::lessThan(results[ndx], minBounds[ndx])) || tcu::boolAny(tcu::greaterThan(results[ndx], maxBounds[ndx])))
2138 log << TestLog::Message << "Fail: " << sts[ndx] << " " << results[ndx] << TestLog::EndMessage;
2139 log << TestLog::Message << " Min : " << minBounds[ndx] << TestLog::EndMessage;
2140 log << TestLog::Message << " Max : " << maxBounds[ndx] << TestLog::EndMessage;
2141 log << TestLog::Message << " Threshold: " << (maxBounds[ndx] - minBounds[ndx]) << TestLog::EndMessage;
2142 log << TestLog::Message << " UMin : " << uvBounds[ndx][0] << TestLog::EndMessage;
2143 log << TestLog::Message << " UMax : " << uvBounds[ndx][1] << TestLog::EndMessage;
2144 log << TestLog::Message << " VMin : " << uvBounds[ndx][2] << TestLog::EndMessage;
2145 log << TestLog::Message << " VMax : " << uvBounds[ndx][3] << TestLog::EndMessage;
2146 log << TestLog::Message << " IMin : " << ijBounds[ndx][0] << TestLog::EndMessage;
2147 log << TestLog::Message << " IMax : " << ijBounds[ndx][1] << TestLog::EndMessage;
2148 log << TestLog::Message << " JMin : " << ijBounds[ndx][2] << TestLog::EndMessage;
2149 log << TestLog::Message << " JMax : " << ijBounds[ndx][3] << TestLog::EndMessage;
2151 if (isXChromaSubsampled(config.format))
2153 log << TestLog::Message << " LumaAlphaValues : " << TestLog::EndMessage;
2154 log << TestLog::Message << " Offset : (" << ijBounds[ndx][0] << ", " << ijBounds[ndx][2] << ")" << TestLog::EndMessage;
2156 for (deInt32 j = ijBounds[ndx][2]; j <= ijBounds[ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
2158 const deInt32 wrappedJ = wrap(config.addressModeV, j, gChannelAccess.getSize().y());
2160 std::ostringstream line;
2162 for (deInt32 i = ijBounds[ndx][0]; i <= ijBounds[ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); i++)
2164 const deInt32 wrappedI = wrap(config.addressModeU, i, gChannelAccess.getSize().x());
2172 line << "(" << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0))
2173 << ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0)) << ")";
2175 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
2179 const IVec2 chromaIRange (divFloor(ijBounds[ndx][0], 2) - 1, divFloor(ijBounds[ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1);
2180 const IVec2 chromaJRange (isYChromaSubsampled(config.format)
2181 ? IVec2(divFloor(ijBounds[ndx][2], 2) - 1, divFloor(ijBounds[ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0), 2) + 1)
2182 : IVec2(ijBounds[ndx][2], ijBounds[ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0)));
2184 log << TestLog::Message << " ChromaValues : " << TestLog::EndMessage;
2185 log << TestLog::Message << " Offset : (" << chromaIRange[0] << ", " << chromaJRange[0] << ")" << TestLog::EndMessage;
2187 for (deInt32 j = chromaJRange[0]; j <= chromaJRange[1]; j++)
2189 const deInt32 wrappedJ = wrap(config.addressModeV, j, rChannelAccess.getSize().y());
2191 std::ostringstream line;
2193 for (deInt32 i = chromaIRange[0]; i <= chromaIRange[1]; i++)
2195 const deInt32 wrappedI = wrap(config.addressModeU, i, rChannelAccess.getSize().x());
2203 line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0))
2204 << ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0)) << ")";
2206 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
2212 log << TestLog::Message << " Values : " << TestLog::EndMessage;
2213 log << TestLog::Message << " Offset : (" << ijBounds[ndx][0] << ", " << ijBounds[ndx][2] << ")" << TestLog::EndMessage;
2215 for (deInt32 j = ijBounds[ndx][2]; j <= ijBounds[ndx][3] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); j++)
2217 const deInt32 wrappedJ = wrap(config.addressModeV, j, rChannelAccess.getSize().y());
2219 std::ostringstream line;
2221 for (deInt32 i = ijBounds[ndx][0]; i <= ijBounds[ndx][1] + (config.textureFilter == vk::VK_FILTER_LINEAR ? 1 : 0); i++)
2223 const deInt32 wrappedI = wrap(config.addressModeU, i, rChannelAccess.getSize().x());
2231 line << "(" << std::setfill(' ') << std::setw(5) << rChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0))
2232 << ", " << std::setfill(' ') << std::setw(5) << gChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0))
2233 << ", " << std::setfill(' ') << std::setw(5) << bChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0))
2234 << ", " << std::setfill(' ') << std::setw(5) << aChannelAccess.getChannelUint(IVec3(wrappedI, wrappedJ, 0)) << ")";
2236 log << TestLog::Message << " " << line.str() << TestLog::EndMessage;
2243 if (errorCount > 30)
2245 log << TestLog::Message << "Encountered " << errorCount << " errors. Omitting rest of the per result logs." << TestLog::EndMessage;
2253 return tcu::TestStatus::pass("Pass");
2255 return tcu::TestStatus::fail("Result comparison failed");
2258 #if defined(FAKE_COLOR_CONVERSION)
2259 const char* swizzleToCompName (const char* identity, vk::VkComponentSwizzle swizzle)
2263 case vk::VK_COMPONENT_SWIZZLE_IDENTITY: return identity;
2264 case vk::VK_COMPONENT_SWIZZLE_R: return "r";
2265 case vk::VK_COMPONENT_SWIZZLE_G: return "g";
2266 case vk::VK_COMPONENT_SWIZZLE_B: return "b";
2267 case vk::VK_COMPONENT_SWIZZLE_A: return "a";
2269 DE_FATAL("Unsupported swizzle");
2275 void createTestShaders (vk::SourceCollections& dst, TestConfig config)
2277 #if !defined(FAKE_COLOR_CONVERSION)
2278 const ShaderSpec spec (createShaderSpec());
2280 generateSources(config.shaderType, spec, dst);
2282 const UVec4 bits (getBitDepth(config.format));
2285 spec.globalDeclarations = "layout(set=" + de::toString((int)EXTRA_RESOURCES_DESCRIPTOR_SET_INDEX) + ", binding=0) uniform highp sampler2D u_sampler;";
2287 spec.inputs.push_back(Symbol("uv", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
2288 spec.outputs.push_back(Symbol("o_color", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
2290 std::ostringstream source;
2292 source << "highp vec4 inputColor = texture(u_sampler, uv);\n";
2294 source << "highp float r = inputColor." << swizzleToCompName("r", config.componentMapping.r) << ";\n";
2295 source << "highp float g = inputColor." << swizzleToCompName("g", config.componentMapping.g) << ";\n";
2296 source << "highp float b = inputColor." << swizzleToCompName("b", config.componentMapping.b) << ";\n";
2297 source << "highp float a = inputColor." << swizzleToCompName("a", config.componentMapping.a) << ";\n";
2299 switch (config.colorRange)
2301 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR:
2302 source << "highp float cr = r - (float(" << (0x1u << (bits[0] - 0x1u)) << ") / float(" << ((0x1u << bits[0]) - 1u) << "));\n";
2303 source << "highp float y = g;\n";
2304 source << "highp float cb = b - (float(" << (0x1u << (bits[2] - 0x1u)) << ") / float(" << ((0x1u << bits[2]) - 1u) << "));\n";
2307 case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR:
2308 source << "highp float cr = (r * float(" << ((0x1u << bits[0]) - 1u) << ") - float(" << (128u * (0x1u << (bits[0] - 8))) << ")) / float(" << (224u * (0x1u << (bits[0] - 8))) << ");\n";
2309 source << "highp float y = (g * float(" << ((0x1u << bits[1]) - 1u) << ") - float(" << (16u * (0x1u << (bits[1] - 8))) << ")) / float(" << (219u * (0x1u << (bits[1] - 8))) << ");\n";
2310 source << "highp float cb = (b * float(" << ((0x1u << bits[2]) - 1u) << ") - float(" << (128u * (0x1u << (bits[2] - 8))) << ")) / float(" << (224u * (0x1u << (bits[2] - 8))) << ");\n";
2314 DE_FATAL("Unknown color range");
2317 source << "highp vec4 color;\n";
2319 switch (config.colorModel)
2321 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR:
2322 source << "color = vec4(r, g, b, a);\n";
2325 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR:
2326 source << "color = vec4(cr, y, cb, a);\n";
2329 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR:
2330 source << "color = vec4(y + 1.402 * cr, y - float(" << (0.202008 / 0.587) << ") * cb - float(" << (0.419198 / 0.587) << ") * cr, y + 1.772 * cb, a);\n";
2333 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR:
2334 source << "color = vec4(y + 1.5748 * cr, y - float(" << (0.13397432 / 0.7152) << ") * cb - float(" << (0.33480248 / 0.7152) << ") * cr, y + 1.8556 * cb, a);\n";
2337 case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR:
2338 source << "color = vec4(y + 1.4746 * cr, (y - float(" << (0.11156702 / 0.6780) << ") * cb) - float(" << (0.38737742 / 0.6780) << ") * cr, y + 1.8814 * cb, a);\n";
2342 DE_FATAL("Unknown color model");
2345 source << "o_color = color;\n";
2347 spec.source = source.str();
2348 generateSources(config.shaderType, spec, dst);
2352 deUint32 getFormatChannelCount (vk::VkFormat format)
2356 case vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16:
2357 case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32:
2358 case vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32:
2359 case vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32:
2360 case vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16:
2361 case vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16:
2362 case vk::VK_FORMAT_B8G8R8A8_UNORM:
2363 case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR:
2364 case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR:
2365 case vk::VK_FORMAT_R16G16B16A16_UNORM:
2366 case vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16:
2367 case vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16:
2368 case vk::VK_FORMAT_R8G8B8A8_UNORM:
2371 case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR:
2372 case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR:
2373 case vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR:
2374 case vk::VK_FORMAT_B5G6R5_UNORM_PACK16:
2375 case vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR:
2376 case vk::VK_FORMAT_B8G8R8_UNORM:
2377 case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR:
2378 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR:
2379 case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR:
2380 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR:
2381 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR:
2382 case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR:
2383 case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR:
2384 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR:
2385 case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR:
2386 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR:
2387 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR:
2388 case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR:
2389 case vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR:
2390 case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR:
2391 case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR:
2392 case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR:
2393 case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR:
2394 case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR:
2395 case vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR:
2396 case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR:
2397 case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR:
2398 case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR:
2399 case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR:
2400 case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR:
2401 case vk::VK_FORMAT_R16G16B16_UNORM:
2402 case vk::VK_FORMAT_R5G6B5_UNORM_PACK16:
2403 case vk::VK_FORMAT_R8G8B8_UNORM:
2406 case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR:
2407 case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR:
2410 case vk::VK_FORMAT_R10X6_UNORM_PACK16_KHR:
2411 case vk::VK_FORMAT_R12X4_UNORM_PACK16_KHR:
2415 DE_FATAL("Unknown number of channels");
2420 struct RangeNamePair
2423 vk::VkSamplerYcbcrRangeKHR value;
2427 struct ChromaLocationNamePair
2430 vk::VkChromaLocationKHR value;
2433 void initTests (tcu::TestCaseGroup* testGroup)
2435 const vk::VkFormat noChromaSubsampledFormats[] =
2437 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16,
2438 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16,
2439 vk::VK_FORMAT_R5G6B5_UNORM_PACK16,
2440 vk::VK_FORMAT_B5G6R5_UNORM_PACK16,
2441 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16,
2442 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16,
2443 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16,
2444 vk::VK_FORMAT_R8G8B8_UNORM,
2445 vk::VK_FORMAT_B8G8R8_UNORM,
2446 vk::VK_FORMAT_R8G8B8A8_UNORM,
2447 vk::VK_FORMAT_B8G8R8A8_UNORM,
2448 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2449 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2450 vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2451 vk::VK_FORMAT_R16G16B16_UNORM,
2452 vk::VK_FORMAT_R16G16B16A16_UNORM,
2453 vk::VK_FORMAT_R10X6_UNORM_PACK16_KHR,
2454 vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16_KHR,
2455 vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16_KHR,
2456 vk::VK_FORMAT_R12X4_UNORM_PACK16_KHR,
2457 vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16_KHR,
2458 vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16_KHR,
2459 vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM_KHR,
2460 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16_KHR,
2461 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16_KHR,
2462 vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM_KHR
2464 const vk::VkFormat xChromaSubsampledFormats[] =
2466 vk::VK_FORMAT_G8B8G8R8_422_UNORM_KHR,
2467 vk::VK_FORMAT_B8G8R8G8_422_UNORM_KHR,
2468 vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM_KHR,
2469 vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM_KHR,
2471 vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16_KHR,
2472 vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16_KHR,
2473 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16_KHR,
2474 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16_KHR,
2475 vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16_KHR,
2476 vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16_KHR,
2477 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16_KHR,
2478 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16_KHR,
2479 vk::VK_FORMAT_G16B16G16R16_422_UNORM_KHR,
2480 vk::VK_FORMAT_B16G16R16G16_422_UNORM_KHR,
2481 vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM_KHR,
2482 vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM_KHR,
2484 const vk::VkFormat xyChromaSubsampledFormats[] =
2486 vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM_KHR,
2487 vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM_KHR,
2488 vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16_KHR,
2489 vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16_KHR,
2490 vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16_KHR,
2491 vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16_KHR,
2492 vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM_KHR,
2493 vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM_KHR,
2497 const char* const name;
2498 const vk::VkSamplerYcbcrModelConversionKHR value;
2501 { "rgb_identity", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR },
2502 { "ycbcr_identity", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY_KHR },
2503 { "ycbcr_709", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709_KHR },
2504 { "ycbcr_601", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601_KHR },
2505 { "ycbcr_2020", vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020_KHR }
2507 const RangeNamePair colorRanges[] =
2509 { "itu_full", vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR },
2510 { "itu_narrow", vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR }
2512 const ChromaLocationNamePair chromaLocations[] =
2514 { "cosited", vk::VK_CHROMA_LOCATION_COSITED_EVEN_KHR },
2515 { "midpoint", vk::VK_CHROMA_LOCATION_MIDPOINT_KHR }
2519 const char* const name;
2521 } textureFilters[] =
2523 { "linear", vk::VK_FILTER_LINEAR },
2524 { "nearest", vk::VK_FILTER_NEAREST }
2526 // Used by the chroma reconstruction tests
2527 const vk::VkSamplerYcbcrModelConversionKHR defaultColorModel (vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR);
2528 const vk::VkSamplerYcbcrRangeKHR defaultColorRange (vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL_KHR);
2529 const vk::VkComponentMapping identitySwizzle =
2531 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
2532 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
2533 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
2534 vk::VK_COMPONENT_SWIZZLE_IDENTITY
2536 const vk::VkComponentMapping swappedChromaSwizzle =
2538 vk::VK_COMPONENT_SWIZZLE_B,
2539 vk::VK_COMPONENT_SWIZZLE_IDENTITY,
2540 vk::VK_COMPONENT_SWIZZLE_R,
2541 vk::VK_COMPONENT_SWIZZLE_IDENTITY
2543 const glu::ShaderType shaderTypes[] =
2545 glu::SHADERTYPE_VERTEX,
2546 glu::SHADERTYPE_FRAGMENT,
2547 glu::SHADERTYPE_COMPUTE
2552 vk::VkImageTiling value;
2555 { "tiling_linear", vk::VK_IMAGE_TILING_LINEAR },
2556 { "tiling_optimal", vk::VK_IMAGE_TILING_OPTIMAL }
2558 tcu::TestContext& testCtx (testGroup->getTestContext());
2559 de::Random rng (1978765638u);
2561 // Test formats without chroma reconstruction
2562 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(noChromaSubsampledFormats); formatNdx++)
2564 const vk::VkFormat format (noChromaSubsampledFormats[formatNdx]);
2565 const std::string formatName (de::toLower(std::string(getFormatName(format)).substr(10)));
2566 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
2568 for (size_t modelNdx = 0; modelNdx < DE_LENGTH_OF_ARRAY(colorModels); modelNdx++)
2570 const char* const colorModelName (colorModels[modelNdx].name);
2571 const vk::VkSamplerYcbcrModelConversionKHR colorModel (colorModels[modelNdx].value);
2573 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR && getFormatChannelCount(format) < 3)
2576 de::MovePtr<tcu::TestCaseGroup> colorModelGroup (new tcu::TestCaseGroup(testCtx, colorModelName, ("Tests for color model " + string(colorModelName)).c_str()));
2578 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR)
2580 for (size_t textureFilterNdx = 0; textureFilterNdx < DE_LENGTH_OF_ARRAY(textureFilters); textureFilterNdx++)
2582 const char* const textureFilterName (textureFilters[textureFilterNdx].name);
2583 const vk::VkFilter textureFilter (textureFilters[textureFilterNdx].value);
2585 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2587 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2588 const char* const tilingName (imageTilings[tilingNdx].name);
2589 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2590 const vk::VkSamplerYcbcrRangeKHR colorRange (rng.choose<RangeNamePair, const RangeNamePair*>(DE_ARRAY_BEGIN(colorRanges), DE_ARRAY_END(colorRanges)).value);
2591 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2593 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2594 textureFilter, chromaLocation, chromaLocation, false, false,
2595 colorRange, colorModel, identitySwizzle);
2597 addFunctionCaseWithPrograms(colorModelGroup.get(), std::string(textureFilterName) + "_" + tilingName, "", createTestShaders, textureConversionTest, config);
2603 for (size_t rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(colorRanges); rangeNdx++)
2605 const char* const colorRangeName (colorRanges[rangeNdx].name);
2606 const vk::VkSamplerYcbcrRangeKHR colorRange (colorRanges[rangeNdx].value);
2608 // Narrow range doesn't really work with formats that have less than 8 bits
2609 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR)
2611 const UVec4 bitDepth (getBitDepth(format));
2613 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
2617 de::MovePtr<tcu::TestCaseGroup> colorRangeGroup (new tcu::TestCaseGroup(testCtx, colorRangeName, ("Tests for color range " + string(colorRangeName)).c_str()));
2619 for (size_t textureFilterNdx = 0; textureFilterNdx < DE_LENGTH_OF_ARRAY(textureFilters); textureFilterNdx++)
2621 const char* const textureFilterName (textureFilters[textureFilterNdx].name);
2622 const vk::VkFilter textureFilter (textureFilters[textureFilterNdx].value);
2624 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2626 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2627 const char* const tilingName (imageTilings[tilingNdx].name);
2628 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2629 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2630 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2631 textureFilter, chromaLocation, chromaLocation, false, false,
2632 colorRange, colorModel, identitySwizzle);
2634 addFunctionCaseWithPrograms(colorRangeGroup.get(), std::string(textureFilterName) + "_" + tilingName, "", createTestShaders, textureConversionTest, config);
2638 colorModelGroup->addChild(colorRangeGroup.release());
2642 formatGroup->addChild(colorModelGroup.release());
2645 testGroup->addChild(formatGroup.release());
2648 // Test formats with x chroma reconstruction
2649 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(xChromaSubsampledFormats); formatNdx++)
2651 const vk::VkFormat format (xChromaSubsampledFormats[formatNdx]);
2652 const std::string formatName (de::toLower(std::string(getFormatName(format)).substr(10)));
2653 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
2655 // Color conversion tests
2657 de::MovePtr<tcu::TestCaseGroup> conversionGroup (new tcu::TestCaseGroup(testCtx, "color_conversion", ""));
2659 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); xChromaOffsetNdx++)
2661 const char* const xChromaOffsetName (chromaLocations[xChromaOffsetNdx].name);
2662 const vk::VkChromaLocationKHR xChromaOffset (chromaLocations[xChromaOffsetNdx].value);
2664 for (size_t modelNdx = 0; modelNdx < DE_LENGTH_OF_ARRAY(colorModels); modelNdx++)
2666 const char* const colorModelName (colorModels[modelNdx].name);
2667 const vk::VkSamplerYcbcrModelConversionKHR colorModel (colorModels[modelNdx].value);
2669 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR && getFormatChannelCount(format) < 3)
2673 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR)
2675 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2677 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2678 const char* const tilingName (imageTilings[tilingNdx].name);
2679 const vk::VkSamplerYcbcrRangeKHR colorRange (rng.choose<RangeNamePair, const RangeNamePair*>(DE_ARRAY_BEGIN(colorRanges), DE_ARRAY_END(colorRanges)).value);
2680 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2681 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2682 const TestConfig config (shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2683 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
2684 colorRange, colorModel, identitySwizzle);
2686 addFunctionCaseWithPrograms(conversionGroup.get(), std::string(colorModelName) + "_" + tilingName + "_" + xChromaOffsetName, "", createTestShaders, textureConversionTest, config);
2691 for (size_t rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(colorRanges); rangeNdx++)
2693 const char* const colorRangeName (colorRanges[rangeNdx].name);
2694 const vk::VkSamplerYcbcrRangeKHR colorRange (colorRanges[rangeNdx].value);
2696 // Narrow range doesn't really work with formats that have less than 8 bits
2697 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR)
2699 const UVec4 bitDepth (getBitDepth(format));
2701 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
2705 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2707 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2708 const char* const tilingName (imageTilings[tilingNdx].name);
2709 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2710 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2711 const TestConfig config (shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2712 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, false, false,
2713 colorRange, colorModel, identitySwizzle);
2715 addFunctionCaseWithPrograms(conversionGroup.get(), (string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + xChromaOffsetName).c_str(), "", createTestShaders, textureConversionTest, config);
2722 formatGroup->addChild(conversionGroup.release());
2725 // Chroma reconstruction tests
2727 de::MovePtr<tcu::TestCaseGroup> reconstrucGroup (new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));
2729 for (size_t textureFilterNdx = 0; textureFilterNdx < DE_LENGTH_OF_ARRAY(textureFilters); textureFilterNdx++)
2731 const char* const textureFilterName (textureFilters[textureFilterNdx].name);
2732 const vk::VkFilter textureFilter (textureFilters[textureFilterNdx].value);
2733 de::MovePtr<tcu::TestCaseGroup> textureFilterGroup (new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));
2735 for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
2737 const bool explicitReconstruction (explicitReconstructionNdx == 1);
2739 for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
2741 const bool disjoint (disjointNdx == 1);
2743 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); xChromaOffsetNdx++)
2745 const vk::VkChromaLocationKHR xChromaOffset (chromaLocations[xChromaOffsetNdx].value);
2746 const char* const xChromaOffsetName (chromaLocations[xChromaOffsetNdx].name);
2748 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2750 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2751 const char* const tilingName (imageTilings[tilingNdx].name);
2754 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2755 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2756 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2757 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2758 defaultColorRange, defaultColorModel, identitySwizzle);
2760 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
2764 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2765 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2766 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2767 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2768 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
2770 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
2773 if (!explicitReconstruction)
2776 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2777 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2778 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2779 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2780 defaultColorRange, defaultColorModel, identitySwizzle);
2782 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
2786 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2787 const vk::VkChromaLocationKHR yChromaOffset (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2788 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2789 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2790 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
2792 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
2798 if (explicitReconstruction)
2800 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2802 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2803 const char* const tilingName (imageTilings[tilingNdx].name);
2805 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2806 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2807 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2808 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
2809 defaultColorRange, defaultColorModel, identitySwizzle);
2811 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
2815 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2816 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2817 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2818 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
2819 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
2821 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
2828 reconstrucGroup->addChild(textureFilterGroup.release());
2831 formatGroup->addChild(reconstrucGroup.release());
2834 testGroup->addChild(formatGroup.release());
2837 // Test formats with xy chroma reconstruction
2838 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(xyChromaSubsampledFormats); formatNdx++)
2840 const vk::VkFormat format (xyChromaSubsampledFormats[formatNdx]);
2841 const std::string formatName (de::toLower(std::string(getFormatName(format)).substr(10)));
2842 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str(), ("Tests for color conversion using format " + formatName).c_str()));
2844 // Color conversion tests
2846 de::MovePtr<tcu::TestCaseGroup> conversionGroup (new tcu::TestCaseGroup(testCtx, "color_conversion", ""));
2848 for (size_t chromaOffsetNdx = 0; chromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); chromaOffsetNdx++)
2850 const char* const chromaOffsetName (chromaLocations[chromaOffsetNdx].name);
2851 const vk::VkChromaLocationKHR chromaOffset (chromaLocations[chromaOffsetNdx].value);
2853 for (size_t modelNdx = 0; modelNdx < DE_LENGTH_OF_ARRAY(colorModels); modelNdx++)
2855 const char* const colorModelName (colorModels[modelNdx].name);
2856 const vk::VkSamplerYcbcrModelConversionKHR colorModel (colorModels[modelNdx].value);
2858 if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR && getFormatChannelCount(format) < 3)
2861 if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY_KHR)
2863 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2865 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2866 const char* const tilingName (imageTilings[tilingNdx].name);
2867 const vk::VkSamplerYcbcrRangeKHR colorRange (rng.choose<RangeNamePair, const RangeNamePair*>(DE_ARRAY_BEGIN(colorRanges), DE_ARRAY_END(colorRanges)).value);
2868 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2869 const TestConfig config (shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2870 vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
2871 colorRange, colorModel, identitySwizzle);
2873 addFunctionCaseWithPrograms(conversionGroup.get(), std::string(colorModelName) + "_" + tilingName + "_" + chromaOffsetName, "", createTestShaders, textureConversionTest, config);
2878 for (size_t rangeNdx = 0; rangeNdx < DE_LENGTH_OF_ARRAY(colorRanges); rangeNdx++)
2880 const char* const colorRangeName (colorRanges[rangeNdx].name);
2881 const vk::VkSamplerYcbcrRangeKHR colorRange (colorRanges[rangeNdx].value);
2883 // Narrow range doesn't really work with formats that have less than 8 bits
2884 if (colorRange == vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW_KHR)
2886 const UVec4 bitDepth (getBitDepth(format));
2888 if (bitDepth[0] < 8 || bitDepth[1] < 8 || bitDepth[2] < 8)
2892 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2894 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2895 const char* const tilingName (imageTilings[tilingNdx].name);
2896 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2897 const TestConfig config (shaderType, format, tiling, vk::VK_FILTER_NEAREST, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2898 vk::VK_FILTER_NEAREST, chromaOffset, chromaOffset, false, false,
2899 colorRange, colorModel, identitySwizzle);
2901 addFunctionCaseWithPrograms(conversionGroup.get(), (string(colorModelName) + "_" + colorRangeName + "_" + tilingName + "_" + chromaOffsetName).c_str(), "", createTestShaders, textureConversionTest, config);
2908 formatGroup->addChild(conversionGroup.release());
2911 // Chroma reconstruction tests
2913 de::MovePtr<tcu::TestCaseGroup> reconstrucGroup (new tcu::TestCaseGroup(testCtx, "chroma_reconstruction", ""));
2915 for (size_t textureFilterNdx = 0; textureFilterNdx < DE_LENGTH_OF_ARRAY(textureFilters); textureFilterNdx++)
2917 const char* const textureFilterName (textureFilters[textureFilterNdx].name);
2918 const vk::VkFilter textureFilter (textureFilters[textureFilterNdx].value);
2919 de::MovePtr<tcu::TestCaseGroup> textureFilterGroup (new tcu::TestCaseGroup(testCtx, textureFilterName, textureFilterName));
2921 for (size_t explicitReconstructionNdx = 0; explicitReconstructionNdx < 2; explicitReconstructionNdx++)
2923 const bool explicitReconstruction (explicitReconstructionNdx == 1);
2925 for (size_t disjointNdx = 0; disjointNdx < 2; disjointNdx++)
2927 const bool disjoint (disjointNdx == 1);
2929 for (size_t xChromaOffsetNdx = 0; xChromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); xChromaOffsetNdx++)
2930 for (size_t yChromaOffsetNdx = 0; yChromaOffsetNdx < DE_LENGTH_OF_ARRAY(chromaLocations); yChromaOffsetNdx++)
2932 const vk::VkChromaLocationKHR xChromaOffset (chromaLocations[xChromaOffsetNdx].value);
2933 const char* const xChromaOffsetName (chromaLocations[xChromaOffsetNdx].name);
2935 const vk::VkChromaLocationKHR yChromaOffset (chromaLocations[yChromaOffsetNdx].value);
2936 const char* const yChromaOffsetName (chromaLocations[yChromaOffsetNdx].name);
2938 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2940 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2941 const char* const tilingName (imageTilings[tilingNdx].name);
2943 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2944 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2945 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2946 defaultColorRange, defaultColorModel, identitySwizzle);
2948 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
2952 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2953 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2954 vk::VK_FILTER_LINEAR, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2955 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
2957 addFunctionCaseWithPrograms(textureFilterGroup.get(), string(explicitReconstruction ? "explicit_linear_" : "default_linear_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
2960 if (!explicitReconstruction)
2963 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2964 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2965 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2966 defaultColorRange, defaultColorModel, identitySwizzle);
2968 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
2972 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2973 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2974 vk::VK_FILTER_NEAREST, xChromaOffset, yChromaOffset, explicitReconstruction, disjoint,
2975 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
2977 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("default_nearest_") + xChromaOffsetName + "_" + yChromaOffsetName + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
2983 if (explicitReconstruction)
2985 for (size_t tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(imageTilings); tilingNdx++)
2987 const vk::VkImageTiling tiling (imageTilings[tilingNdx].value);
2988 const char* const tilingName (imageTilings[tilingNdx].name);
2990 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
2991 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
2992 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
2993 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
2994 defaultColorRange, defaultColorModel, identitySwizzle);
2996 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : ""), "", createTestShaders, textureConversionTest, config);
3000 const glu::ShaderType shaderType (rng.choose<glu::ShaderType>(DE_ARRAY_BEGIN(shaderTypes), DE_ARRAY_END(shaderTypes)));
3001 const vk::VkChromaLocationKHR chromaLocation (rng.choose<ChromaLocationNamePair, const ChromaLocationNamePair*>(DE_ARRAY_BEGIN(chromaLocations), DE_ARRAY_END(chromaLocations)).value);
3002 const TestConfig config (shaderType, format, tiling, textureFilter, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
3003 vk::VK_FILTER_NEAREST, chromaLocation, chromaLocation, explicitReconstruction, disjoint,
3004 defaultColorRange, defaultColorModel, swappedChromaSwizzle);
3006 addFunctionCaseWithPrograms(textureFilterGroup.get(), string("explicit_nearest") + "_" + tilingName + (disjoint ? "_disjoint" : "") + "_swapped_chroma", "", createTestShaders, textureConversionTest, config);
3013 reconstrucGroup->addChild(textureFilterGroup.release());
3016 formatGroup->addChild(reconstrucGroup.release());
3019 testGroup->addChild(formatGroup.release());
3025 tcu::TestCaseGroup* createConversionTests (tcu::TestContext& testCtx)
3027 return createTestGroup(testCtx, "conversion", "Sampler YCbCr Conversion Tests", initTests);