1e5c31af7Sopenharmony_ci/*------------------------------------------------------------------------- 2e5c31af7Sopenharmony_ci * Vulkan Conformance Tests 3e5c31af7Sopenharmony_ci * ------------------------ 4e5c31af7Sopenharmony_ci * 5e5c31af7Sopenharmony_ci * Copyright (c) 2019 Google Inc. 6e5c31af7Sopenharmony_ci * Copyright (c) 2019 The Khronos Group Inc. 7e5c31af7Sopenharmony_ci * 8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License. 10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at 11e5c31af7Sopenharmony_ci * 12e5c31af7Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 13e5c31af7Sopenharmony_ci * 14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and 18e5c31af7Sopenharmony_ci * limitations under the License. 19e5c31af7Sopenharmony_ci * 20e5c31af7Sopenharmony_ci *//*! 21e5c31af7Sopenharmony_ci * \file 22e5c31af7Sopenharmony_ci * \brief YCbCr Test Utilities 23e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/ 24e5c31af7Sopenharmony_ci 25e5c31af7Sopenharmony_ci#include "vktYCbCrUtil.hpp" 26e5c31af7Sopenharmony_ci 27e5c31af7Sopenharmony_ci#include "vkQueryUtil.hpp" 28e5c31af7Sopenharmony_ci#include "vkRefUtil.hpp" 29e5c31af7Sopenharmony_ci#include "vkTypeUtil.hpp" 30e5c31af7Sopenharmony_ci#include "vkCmdUtil.hpp" 31e5c31af7Sopenharmony_ci 32e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp" 33e5c31af7Sopenharmony_ci#include "deMath.h" 34e5c31af7Sopenharmony_ci#include "deFloat16.h" 35e5c31af7Sopenharmony_ci#include "tcuVector.hpp" 36e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp" 37e5c31af7Sopenharmony_ci 38e5c31af7Sopenharmony_ci#include "deSTLUtil.hpp" 39e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp" 40e5c31af7Sopenharmony_ci 41e5c31af7Sopenharmony_ci#include <limits> 42e5c31af7Sopenharmony_ci 43e5c31af7Sopenharmony_cinamespace vkt 44e5c31af7Sopenharmony_ci{ 45e5c31af7Sopenharmony_cinamespace ycbcr 46e5c31af7Sopenharmony_ci{ 47e5c31af7Sopenharmony_ci 48e5c31af7Sopenharmony_ciusing namespace vk; 49e5c31af7Sopenharmony_ci 50e5c31af7Sopenharmony_ciusing de::MovePtr; 51e5c31af7Sopenharmony_ciusing tcu::FloatFormat; 52e5c31af7Sopenharmony_ciusing tcu::Interval; 53e5c31af7Sopenharmony_ciusing tcu::IVec2; 54e5c31af7Sopenharmony_ciusing tcu::IVec4; 55e5c31af7Sopenharmony_ciusing tcu::UVec2; 56e5c31af7Sopenharmony_ciusing tcu::UVec4; 57e5c31af7Sopenharmony_ciusing tcu::Vec2; 58e5c31af7Sopenharmony_ciusing tcu::Vec4; 59e5c31af7Sopenharmony_ciusing std::vector; 60e5c31af7Sopenharmony_ciusing std::string; 61e5c31af7Sopenharmony_ci 62e5c31af7Sopenharmony_ci// MultiPlaneImageData 63e5c31af7Sopenharmony_ci 64e5c31af7Sopenharmony_ciMultiPlaneImageData::MultiPlaneImageData (VkFormat format, const UVec2& size) 65e5c31af7Sopenharmony_ci : m_format (format) 66e5c31af7Sopenharmony_ci , m_description (getPlanarFormatDescription(format)) 67e5c31af7Sopenharmony_ci , m_size (size) 68e5c31af7Sopenharmony_ci{ 69e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx) 70e5c31af7Sopenharmony_ci m_planeData[planeNdx].resize(getPlaneSizeInBytes(m_description, size, planeNdx, 0, BUFFER_IMAGE_COPY_OFFSET_GRANULARITY)); 71e5c31af7Sopenharmony_ci} 72e5c31af7Sopenharmony_ci 73e5c31af7Sopenharmony_ciMultiPlaneImageData::MultiPlaneImageData (const MultiPlaneImageData& other) 74e5c31af7Sopenharmony_ci : m_format (other.m_format) 75e5c31af7Sopenharmony_ci , m_description (other.m_description) 76e5c31af7Sopenharmony_ci , m_size (other.m_size) 77e5c31af7Sopenharmony_ci{ 78e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx) 79e5c31af7Sopenharmony_ci m_planeData[planeNdx] = other.m_planeData[planeNdx]; 80e5c31af7Sopenharmony_ci} 81e5c31af7Sopenharmony_ci 82e5c31af7Sopenharmony_ciMultiPlaneImageData::~MultiPlaneImageData (void) 83e5c31af7Sopenharmony_ci{ 84e5c31af7Sopenharmony_ci} 85e5c31af7Sopenharmony_ci 86e5c31af7Sopenharmony_citcu::PixelBufferAccess MultiPlaneImageData::getChannelAccess (deUint32 channelNdx) 87e5c31af7Sopenharmony_ci{ 88e5c31af7Sopenharmony_ci void* planePtrs[PlanarFormatDescription::MAX_PLANES]; 89e5c31af7Sopenharmony_ci deUint32 planeRowPitches[PlanarFormatDescription::MAX_PLANES]; 90e5c31af7Sopenharmony_ci 91e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx) 92e5c31af7Sopenharmony_ci { 93e5c31af7Sopenharmony_ci const deUint32 planeW = m_size.x() / ( m_description.blockWidth * m_description.planes[planeNdx].widthDivisor); 94e5c31af7Sopenharmony_ci planeRowPitches[planeNdx] = m_description.planes[planeNdx].elementSizeBytes * planeW; 95e5c31af7Sopenharmony_ci planePtrs[planeNdx] = &m_planeData[planeNdx][0]; 96e5c31af7Sopenharmony_ci } 97e5c31af7Sopenharmony_ci 98e5c31af7Sopenharmony_ci return vk::getChannelAccess(m_description, 99e5c31af7Sopenharmony_ci m_size, 100e5c31af7Sopenharmony_ci planeRowPitches, 101e5c31af7Sopenharmony_ci planePtrs, 102e5c31af7Sopenharmony_ci channelNdx); 103e5c31af7Sopenharmony_ci} 104e5c31af7Sopenharmony_ci 105e5c31af7Sopenharmony_citcu::ConstPixelBufferAccess MultiPlaneImageData::getChannelAccess (deUint32 channelNdx) const 106e5c31af7Sopenharmony_ci{ 107e5c31af7Sopenharmony_ci const void* planePtrs[PlanarFormatDescription::MAX_PLANES]; 108e5c31af7Sopenharmony_ci deUint32 planeRowPitches[PlanarFormatDescription::MAX_PLANES]; 109e5c31af7Sopenharmony_ci 110e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < m_description.numPlanes; ++planeNdx) 111e5c31af7Sopenharmony_ci { 112e5c31af7Sopenharmony_ci const deUint32 planeW = m_size.x() / (m_description.blockWidth * m_description.planes[planeNdx].widthDivisor); 113e5c31af7Sopenharmony_ci planeRowPitches[planeNdx] = m_description.planes[planeNdx].elementSizeBytes * planeW; 114e5c31af7Sopenharmony_ci planePtrs[planeNdx] = &m_planeData[planeNdx][0]; 115e5c31af7Sopenharmony_ci } 116e5c31af7Sopenharmony_ci 117e5c31af7Sopenharmony_ci return vk::getChannelAccess(m_description, 118e5c31af7Sopenharmony_ci m_size, 119e5c31af7Sopenharmony_ci planeRowPitches, 120e5c31af7Sopenharmony_ci planePtrs, 121e5c31af7Sopenharmony_ci channelNdx); 122e5c31af7Sopenharmony_ci} 123e5c31af7Sopenharmony_ci 124e5c31af7Sopenharmony_ci// Misc utilities 125e5c31af7Sopenharmony_ci 126e5c31af7Sopenharmony_cinamespace 127e5c31af7Sopenharmony_ci{ 128e5c31af7Sopenharmony_ci 129e5c31af7Sopenharmony_civoid allocateStagingBuffers (const DeviceInterface& vkd, 130e5c31af7Sopenharmony_ci VkDevice device, 131e5c31af7Sopenharmony_ci Allocator& allocator, 132e5c31af7Sopenharmony_ci const MultiPlaneImageData& imageData, 133e5c31af7Sopenharmony_ci vector<VkBufferSp>* buffers, 134e5c31af7Sopenharmony_ci vector<AllocationSp>* allocations) 135e5c31af7Sopenharmony_ci{ 136e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx) 137e5c31af7Sopenharmony_ci { 138e5c31af7Sopenharmony_ci const VkBufferCreateInfo bufferInfo = 139e5c31af7Sopenharmony_ci { 140e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 141e5c31af7Sopenharmony_ci DE_NULL, 142e5c31af7Sopenharmony_ci (VkBufferCreateFlags)0u, 143e5c31af7Sopenharmony_ci (VkDeviceSize)imageData.getPlaneSize(planeNdx), 144e5c31af7Sopenharmony_ci VK_BUFFER_USAGE_TRANSFER_SRC_BIT|VK_BUFFER_USAGE_TRANSFER_DST_BIT, 145e5c31af7Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, 146e5c31af7Sopenharmony_ci 0u, 147e5c31af7Sopenharmony_ci (const deUint32*)DE_NULL, 148e5c31af7Sopenharmony_ci }; 149e5c31af7Sopenharmony_ci Move<VkBuffer> buffer (createBuffer(vkd, device, &bufferInfo)); 150e5c31af7Sopenharmony_ci MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer), 151e5c31af7Sopenharmony_ci MemoryRequirement::HostVisible|MemoryRequirement::Any)); 152e5c31af7Sopenharmony_ci 153e5c31af7Sopenharmony_ci VK_CHECK(vkd.bindBufferMemory(device, *buffer, allocation->getMemory(), allocation->getOffset())); 154e5c31af7Sopenharmony_ci 155e5c31af7Sopenharmony_ci buffers->push_back(VkBufferSp(new Unique<VkBuffer>(buffer))); 156e5c31af7Sopenharmony_ci allocations->push_back(AllocationSp(allocation.release())); 157e5c31af7Sopenharmony_ci } 158e5c31af7Sopenharmony_ci} 159e5c31af7Sopenharmony_ci 160e5c31af7Sopenharmony_civoid allocateAndWriteStagingBuffers (const DeviceInterface& vkd, 161e5c31af7Sopenharmony_ci VkDevice device, 162e5c31af7Sopenharmony_ci Allocator& allocator, 163e5c31af7Sopenharmony_ci const MultiPlaneImageData& imageData, 164e5c31af7Sopenharmony_ci vector<VkBufferSp>* buffers, 165e5c31af7Sopenharmony_ci vector<AllocationSp>* allocations) 166e5c31af7Sopenharmony_ci{ 167e5c31af7Sopenharmony_ci allocateStagingBuffers(vkd, device, allocator, imageData, buffers, allocations); 168e5c31af7Sopenharmony_ci 169e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx) 170e5c31af7Sopenharmony_ci { 171e5c31af7Sopenharmony_ci deMemcpy((*allocations)[planeNdx]->getHostPtr(), imageData.getPlanePtr(planeNdx), imageData.getPlaneSize(planeNdx)); 172e5c31af7Sopenharmony_ci flushMappedMemoryRange(vkd, device, (*allocations)[planeNdx]->getMemory(), 0u, VK_WHOLE_SIZE); 173e5c31af7Sopenharmony_ci } 174e5c31af7Sopenharmony_ci} 175e5c31af7Sopenharmony_ci 176e5c31af7Sopenharmony_civoid readStagingBuffers (MultiPlaneImageData* imageData, 177e5c31af7Sopenharmony_ci const DeviceInterface& vkd, 178e5c31af7Sopenharmony_ci VkDevice device, 179e5c31af7Sopenharmony_ci const vector<AllocationSp>& allocations) 180e5c31af7Sopenharmony_ci{ 181e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx) 182e5c31af7Sopenharmony_ci { 183e5c31af7Sopenharmony_ci invalidateMappedMemoryRange(vkd, device, allocations[planeNdx]->getMemory(), 0u, VK_WHOLE_SIZE); 184e5c31af7Sopenharmony_ci deMemcpy(imageData->getPlanePtr(planeNdx), allocations[planeNdx]->getHostPtr(), imageData->getPlaneSize(planeNdx)); 185e5c31af7Sopenharmony_ci } 186e5c31af7Sopenharmony_ci} 187e5c31af7Sopenharmony_ci 188e5c31af7Sopenharmony_ci} // anonymous 189e5c31af7Sopenharmony_ci 190e5c31af7Sopenharmony_civoid checkImageSupport (Context& context, VkFormat format, VkImageCreateFlags createFlags, VkImageTiling tiling) 191e5c31af7Sopenharmony_ci{ 192e5c31af7Sopenharmony_ci const bool disjoint = (createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0; 193e5c31af7Sopenharmony_ci const VkPhysicalDeviceSamplerYcbcrConversionFeatures features = context.getSamplerYcbcrConversionFeatures(); 194e5c31af7Sopenharmony_ci 195e5c31af7Sopenharmony_ci if (features.samplerYcbcrConversion == VK_FALSE) 196e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "samplerYcbcrConversion is not supported"); 197e5c31af7Sopenharmony_ci 198e5c31af7Sopenharmony_ci if (disjoint) 199e5c31af7Sopenharmony_ci { 200e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_bind_memory2"); 201e5c31af7Sopenharmony_ci context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2"); 202e5c31af7Sopenharmony_ci } 203e5c31af7Sopenharmony_ci 204e5c31af7Sopenharmony_ci { 205e5c31af7Sopenharmony_ci const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(), 206e5c31af7Sopenharmony_ci context.getPhysicalDevice(), 207e5c31af7Sopenharmony_ci format); 208e5c31af7Sopenharmony_ci const VkFormatFeatureFlags featureFlags = tiling == VK_IMAGE_TILING_OPTIMAL 209e5c31af7Sopenharmony_ci ? formatProperties.optimalTilingFeatures 210e5c31af7Sopenharmony_ci : formatProperties.linearTilingFeatures; 211e5c31af7Sopenharmony_ci 212e5c31af7Sopenharmony_ci if ((featureFlags & (VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT | VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT)) == 0) 213e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "YCbCr conversion is not supported for format"); 214e5c31af7Sopenharmony_ci 215e5c31af7Sopenharmony_ci if (disjoint && ((featureFlags & VK_FORMAT_FEATURE_DISJOINT_BIT) == 0)) 216e5c31af7Sopenharmony_ci TCU_THROW(NotSupportedError, "Disjoint planes are not supported for format"); 217e5c31af7Sopenharmony_ci } 218e5c31af7Sopenharmony_ci} 219e5c31af7Sopenharmony_ci 220e5c31af7Sopenharmony_civoid fillRandomNoNaN(de::Random* randomGen, deUint8* const data, deUint32 size, const vk::VkFormat format) 221e5c31af7Sopenharmony_ci{ 222e5c31af7Sopenharmony_ci bool isFloat = false; 223e5c31af7Sopenharmony_ci deUint32 stride = 1; 224e5c31af7Sopenharmony_ci 225e5c31af7Sopenharmony_ci switch (format) 226e5c31af7Sopenharmony_ci { 227e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B10G11R11_UFLOAT_PACK32: 228e5c31af7Sopenharmony_ci isFloat = true; 229e5c31af7Sopenharmony_ci stride = 1; 230e5c31af7Sopenharmony_ci break; 231e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16_SFLOAT: 232e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16G16_SFLOAT: 233e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16G16B16_SFLOAT: 234e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16G16B16A16_SFLOAT: 235e5c31af7Sopenharmony_ci isFloat = true; 236e5c31af7Sopenharmony_ci stride = 2; 237e5c31af7Sopenharmony_ci break; 238e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R32_SFLOAT: 239e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R32G32_SFLOAT: 240e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R32G32B32_SFLOAT: 241e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R32G32B32A32_SFLOAT: 242e5c31af7Sopenharmony_ci isFloat = true; 243e5c31af7Sopenharmony_ci stride = 4; 244e5c31af7Sopenharmony_ci break; 245e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R64_SFLOAT: 246e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R64G64_SFLOAT: 247e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R64G64B64_SFLOAT: 248e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R64G64B64A64_SFLOAT: 249e5c31af7Sopenharmony_ci isFloat = true; 250e5c31af7Sopenharmony_ci stride = 8; 251e5c31af7Sopenharmony_ci break; 252e5c31af7Sopenharmony_ci default: 253e5c31af7Sopenharmony_ci stride = 1; 254e5c31af7Sopenharmony_ci break; 255e5c31af7Sopenharmony_ci } 256e5c31af7Sopenharmony_ci 257e5c31af7Sopenharmony_ci if (isFloat) { 258e5c31af7Sopenharmony_ci deUint32 ndx = 0; 259e5c31af7Sopenharmony_ci for (; ndx < size - stride + 1; ndx += stride) 260e5c31af7Sopenharmony_ci { 261e5c31af7Sopenharmony_ci if (stride == 1) { 262e5c31af7Sopenharmony_ci // Set first bit of each channel to 0 to avoid NaNs, only format is B10G11R11 263e5c31af7Sopenharmony_ci const deUint8 mask[] = { 0x7F, 0xDF, 0xFB, 0xFF }; 264e5c31af7Sopenharmony_ci // Apply mask for both endians 265e5c31af7Sopenharmony_ci data[ndx] = (randomGen->getUint8() & mask[ndx % 4]) & mask[3 - ndx % 4]; 266e5c31af7Sopenharmony_ci } 267e5c31af7Sopenharmony_ci else if (stride == 2) 268e5c31af7Sopenharmony_ci { 269e5c31af7Sopenharmony_ci deFloat16* ptr = reinterpret_cast<deFloat16*>(&data[ndx]); 270e5c31af7Sopenharmony_ci *ptr = deFloat32To16(randomGen->getFloat()); 271e5c31af7Sopenharmony_ci } 272e5c31af7Sopenharmony_ci else if (stride == 4) 273e5c31af7Sopenharmony_ci { 274e5c31af7Sopenharmony_ci float* ptr = reinterpret_cast<float*>(&data[ndx]); 275e5c31af7Sopenharmony_ci *ptr = randomGen->getFloat(); 276e5c31af7Sopenharmony_ci } 277e5c31af7Sopenharmony_ci else if (stride == 8) 278e5c31af7Sopenharmony_ci { 279e5c31af7Sopenharmony_ci double* ptr = reinterpret_cast<double*>(&data[ndx]); 280e5c31af7Sopenharmony_ci *ptr = randomGen->getDouble(); 281e5c31af7Sopenharmony_ci } 282e5c31af7Sopenharmony_ci } 283e5c31af7Sopenharmony_ci while (ndx < size) { 284e5c31af7Sopenharmony_ci data[ndx] = 0; 285e5c31af7Sopenharmony_ci } 286e5c31af7Sopenharmony_ci } 287e5c31af7Sopenharmony_ci else 288e5c31af7Sopenharmony_ci { 289e5c31af7Sopenharmony_ci for (deUint32 ndx = 0; ndx < size; ++ndx) 290e5c31af7Sopenharmony_ci { 291e5c31af7Sopenharmony_ci data[ndx] = randomGen->getUint8(); 292e5c31af7Sopenharmony_ci } 293e5c31af7Sopenharmony_ci } 294e5c31af7Sopenharmony_ci} 295e5c31af7Sopenharmony_ci 296e5c31af7Sopenharmony_ci// When noNan is true, fillRandom does not generate NaNs in float formats. 297e5c31af7Sopenharmony_civoid fillRandom (de::Random* randomGen, MultiPlaneImageData* imageData, const vk::VkFormat format, const bool noNan) 298e5c31af7Sopenharmony_ci{ 299e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx) 300e5c31af7Sopenharmony_ci { 301e5c31af7Sopenharmony_ci const size_t planeSize = imageData->getPlaneSize(planeNdx); 302e5c31af7Sopenharmony_ci deUint8* const planePtr = (deUint8*)imageData->getPlanePtr(planeNdx); 303e5c31af7Sopenharmony_ci 304e5c31af7Sopenharmony_ci if (noNan) { 305e5c31af7Sopenharmony_ci fillRandomNoNaN(randomGen, planePtr, (deUint32)planeSize, format); 306e5c31af7Sopenharmony_ci } 307e5c31af7Sopenharmony_ci else 308e5c31af7Sopenharmony_ci { 309e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < planeSize; ++ndx) 310e5c31af7Sopenharmony_ci { 311e5c31af7Sopenharmony_ci planePtr[ndx] = randomGen->getUint8(); 312e5c31af7Sopenharmony_ci } 313e5c31af7Sopenharmony_ci } 314e5c31af7Sopenharmony_ci } 315e5c31af7Sopenharmony_ci} 316e5c31af7Sopenharmony_ci 317e5c31af7Sopenharmony_civoid fillGradient (MultiPlaneImageData* imageData, const tcu::Vec4& minVal, const tcu::Vec4& maxVal) 318e5c31af7Sopenharmony_ci{ 319e5c31af7Sopenharmony_ci const PlanarFormatDescription& formatInfo = imageData->getDescription(); 320e5c31af7Sopenharmony_ci 321e5c31af7Sopenharmony_ci // \todo [pyry] Optimize: no point in re-rendering source gradient for each channel. 322e5c31af7Sopenharmony_ci 323e5c31af7Sopenharmony_ci for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++) 324e5c31af7Sopenharmony_ci { 325e5c31af7Sopenharmony_ci if (formatInfo.hasChannelNdx(channelNdx)) 326e5c31af7Sopenharmony_ci { 327e5c31af7Sopenharmony_ci const tcu::PixelBufferAccess channelAccess = imageData->getChannelAccess(channelNdx); 328e5c31af7Sopenharmony_ci tcu::TextureLevel tmpTexture (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), channelAccess.getWidth(), channelAccess.getHeight()); 329e5c31af7Sopenharmony_ci const tcu::ConstPixelBufferAccess tmpAccess = tmpTexture.getAccess(); 330e5c31af7Sopenharmony_ci 331e5c31af7Sopenharmony_ci tcu::fillWithComponentGradients(tmpTexture, minVal, maxVal); 332e5c31af7Sopenharmony_ci 333e5c31af7Sopenharmony_ci for (int y = 0; y < channelAccess.getHeight(); ++y) 334e5c31af7Sopenharmony_ci for (int x = 0; x < channelAccess.getWidth(); ++x) 335e5c31af7Sopenharmony_ci { 336e5c31af7Sopenharmony_ci channelAccess.setPixel(tcu::Vec4(tmpAccess.getPixel(x, y)[channelNdx]), x, y); 337e5c31af7Sopenharmony_ci } 338e5c31af7Sopenharmony_ci } 339e5c31af7Sopenharmony_ci } 340e5c31af7Sopenharmony_ci} 341e5c31af7Sopenharmony_ci 342e5c31af7Sopenharmony_civoid fillZero (MultiPlaneImageData* imageData) 343e5c31af7Sopenharmony_ci{ 344e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx) 345e5c31af7Sopenharmony_ci deMemset(imageData->getPlanePtr(planeNdx), 0, imageData->getPlaneSize(planeNdx)); 346e5c31af7Sopenharmony_ci} 347e5c31af7Sopenharmony_ci 348e5c31af7Sopenharmony_civector<AllocationSp> allocateAndBindImageMemory (const DeviceInterface& vkd, 349e5c31af7Sopenharmony_ci VkDevice device, 350e5c31af7Sopenharmony_ci Allocator& allocator, 351e5c31af7Sopenharmony_ci VkImage image, 352e5c31af7Sopenharmony_ci VkFormat format, 353e5c31af7Sopenharmony_ci VkImageCreateFlags createFlags, 354e5c31af7Sopenharmony_ci vk::MemoryRequirement requirement) 355e5c31af7Sopenharmony_ci{ 356e5c31af7Sopenharmony_ci vector<AllocationSp> allocations; 357e5c31af7Sopenharmony_ci 358e5c31af7Sopenharmony_ci if ((createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0) 359e5c31af7Sopenharmony_ci { 360e5c31af7Sopenharmony_ci const deUint32 numPlanes = getPlaneCount(format); 361e5c31af7Sopenharmony_ci 362e5c31af7Sopenharmony_ci bindImagePlanesMemory(vkd, device, image, numPlanes, allocations, allocator, requirement); 363e5c31af7Sopenharmony_ci } 364e5c31af7Sopenharmony_ci else 365e5c31af7Sopenharmony_ci { 366e5c31af7Sopenharmony_ci const VkMemoryRequirements reqs = getImageMemoryRequirements(vkd, device, image); 367e5c31af7Sopenharmony_ci 368e5c31af7Sopenharmony_ci allocations.push_back(AllocationSp(allocator.allocate(reqs, requirement).release())); 369e5c31af7Sopenharmony_ci 370e5c31af7Sopenharmony_ci VK_CHECK(vkd.bindImageMemory(device, image, allocations.back()->getMemory(), allocations.back()->getOffset())); 371e5c31af7Sopenharmony_ci } 372e5c31af7Sopenharmony_ci 373e5c31af7Sopenharmony_ci return allocations; 374e5c31af7Sopenharmony_ci} 375e5c31af7Sopenharmony_ci 376e5c31af7Sopenharmony_civoid uploadImage (const DeviceInterface& vkd, 377e5c31af7Sopenharmony_ci VkDevice device, 378e5c31af7Sopenharmony_ci deUint32 queueFamilyNdx, 379e5c31af7Sopenharmony_ci Allocator& allocator, 380e5c31af7Sopenharmony_ci VkImage image, 381e5c31af7Sopenharmony_ci const MultiPlaneImageData& imageData, 382e5c31af7Sopenharmony_ci VkAccessFlags nextAccess, 383e5c31af7Sopenharmony_ci VkImageLayout finalLayout, 384e5c31af7Sopenharmony_ci deUint32 arrayLayer) 385e5c31af7Sopenharmony_ci{ 386e5c31af7Sopenharmony_ci const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u); 387e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx)); 388e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 389e5c31af7Sopenharmony_ci vector<VkBufferSp> stagingBuffers; 390e5c31af7Sopenharmony_ci vector<AllocationSp> stagingMemory; 391e5c31af7Sopenharmony_ci 392e5c31af7Sopenharmony_ci const PlanarFormatDescription& formatDesc = imageData.getDescription(); 393e5c31af7Sopenharmony_ci 394e5c31af7Sopenharmony_ci allocateAndWriteStagingBuffers(vkd, device, allocator, imageData, &stagingBuffers, &stagingMemory); 395e5c31af7Sopenharmony_ci 396e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, *cmdBuffer); 397e5c31af7Sopenharmony_ci 398e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData.getDescription().numPlanes; ++planeNdx) 399e5c31af7Sopenharmony_ci { 400e5c31af7Sopenharmony_ci const VkImageAspectFlagBits aspect = (formatDesc.numPlanes > 1) 401e5c31af7Sopenharmony_ci ? getPlaneAspect(planeNdx) 402e5c31af7Sopenharmony_ci : VK_IMAGE_ASPECT_COLOR_BIT; 403e5c31af7Sopenharmony_ci const VkExtent3D imageExtent = makeExtent3D(imageData.getSize().x(), imageData.getSize().y(), 1u); 404e5c31af7Sopenharmony_ci const VkExtent3D planeExtent = getPlaneExtent(formatDesc, imageExtent, planeNdx, 0); 405e5c31af7Sopenharmony_ci const VkBufferImageCopy copy = 406e5c31af7Sopenharmony_ci { 407e5c31af7Sopenharmony_ci 0u, // bufferOffset 408e5c31af7Sopenharmony_ci 0u, // bufferRowLength 409e5c31af7Sopenharmony_ci 0u, // bufferImageHeight 410e5c31af7Sopenharmony_ci { (VkImageAspectFlags)aspect, 0u, arrayLayer, 1u }, 411e5c31af7Sopenharmony_ci makeOffset3D(0u, 0u, 0u), 412e5c31af7Sopenharmony_ci planeExtent 413e5c31af7Sopenharmony_ci }; 414e5c31af7Sopenharmony_ci 415e5c31af7Sopenharmony_ci { 416e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyBarrier = 417e5c31af7Sopenharmony_ci { 418e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 419e5c31af7Sopenharmony_ci DE_NULL, 420e5c31af7Sopenharmony_ci (VkAccessFlags)0, 421e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, 422e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_UNDEFINED, 423e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 424e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 425e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 426e5c31af7Sopenharmony_ci image, 427e5c31af7Sopenharmony_ci { (VkImageAspectFlags)aspect, 0u, 1u, arrayLayer, 1u } 428e5c31af7Sopenharmony_ci }; 429e5c31af7Sopenharmony_ci 430e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 431e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT, 432e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT, 433e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 434e5c31af7Sopenharmony_ci 0u, 435e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 436e5c31af7Sopenharmony_ci 0u, 437e5c31af7Sopenharmony_ci (const VkBufferMemoryBarrier*)DE_NULL, 438e5c31af7Sopenharmony_ci 1u, 439e5c31af7Sopenharmony_ci &preCopyBarrier); 440e5c31af7Sopenharmony_ci } 441e5c31af7Sopenharmony_ci 442e5c31af7Sopenharmony_ci vkd.cmdCopyBufferToImage(*cmdBuffer, **stagingBuffers[planeNdx], image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©); 443e5c31af7Sopenharmony_ci 444e5c31af7Sopenharmony_ci { 445e5c31af7Sopenharmony_ci const VkImageMemoryBarrier postCopyBarrier = 446e5c31af7Sopenharmony_ci { 447e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 448e5c31af7Sopenharmony_ci DE_NULL, 449e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, 450e5c31af7Sopenharmony_ci nextAccess, 451e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 452e5c31af7Sopenharmony_ci finalLayout, 453e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 454e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 455e5c31af7Sopenharmony_ci image, 456e5c31af7Sopenharmony_ci { (VkImageAspectFlags)aspect, 0u, 1u, arrayLayer, 1u } 457e5c31af7Sopenharmony_ci }; 458e5c31af7Sopenharmony_ci 459e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 460e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT, 461e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 462e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 463e5c31af7Sopenharmony_ci 0u, 464e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 465e5c31af7Sopenharmony_ci 0u, 466e5c31af7Sopenharmony_ci (const VkBufferMemoryBarrier*)DE_NULL, 467e5c31af7Sopenharmony_ci 1u, 468e5c31af7Sopenharmony_ci &postCopyBarrier); 469e5c31af7Sopenharmony_ci } 470e5c31af7Sopenharmony_ci 471e5c31af7Sopenharmony_ci } 472e5c31af7Sopenharmony_ci 473e5c31af7Sopenharmony_ci endCommandBuffer(vkd, *cmdBuffer); 474e5c31af7Sopenharmony_ci 475e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, *cmdBuffer); 476e5c31af7Sopenharmony_ci} 477e5c31af7Sopenharmony_ci 478e5c31af7Sopenharmony_civoid fillImageMemory (const vk::DeviceInterface& vkd, 479e5c31af7Sopenharmony_ci vk::VkDevice device, 480e5c31af7Sopenharmony_ci deUint32 queueFamilyNdx, 481e5c31af7Sopenharmony_ci vk::VkImage image, 482e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<vk::Allocation> >& allocations, 483e5c31af7Sopenharmony_ci const MultiPlaneImageData& imageData, 484e5c31af7Sopenharmony_ci vk::VkAccessFlags nextAccess, 485e5c31af7Sopenharmony_ci vk::VkImageLayout finalLayout, 486e5c31af7Sopenharmony_ci deUint32 arrayLayer) 487e5c31af7Sopenharmony_ci{ 488e5c31af7Sopenharmony_ci const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u); 489e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx)); 490e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 491e5c31af7Sopenharmony_ci const PlanarFormatDescription& formatDesc = imageData.getDescription(); 492e5c31af7Sopenharmony_ci 493e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < formatDesc.numPlanes; ++planeNdx) 494e5c31af7Sopenharmony_ci { 495e5c31af7Sopenharmony_ci const VkImageAspectFlagBits aspect = (formatDesc.numPlanes > 1) 496e5c31af7Sopenharmony_ci ? getPlaneAspect(planeNdx) 497e5c31af7Sopenharmony_ci : VK_IMAGE_ASPECT_COLOR_BIT; 498e5c31af7Sopenharmony_ci const de::SharedPtr<Allocation>& allocation = allocations.size() > 1 499e5c31af7Sopenharmony_ci ? allocations[planeNdx] 500e5c31af7Sopenharmony_ci : allocations[0]; 501e5c31af7Sopenharmony_ci const size_t planeSize = imageData.getPlaneSize(planeNdx); 502e5c31af7Sopenharmony_ci const deUint32 planeH = imageData.getSize().y() / formatDesc.planes[planeNdx].heightDivisor; 503e5c31af7Sopenharmony_ci const VkImageSubresource subresource = 504e5c31af7Sopenharmony_ci { 505e5c31af7Sopenharmony_ci static_cast<vk::VkImageAspectFlags>(aspect), 506e5c31af7Sopenharmony_ci 0u, 507e5c31af7Sopenharmony_ci arrayLayer, 508e5c31af7Sopenharmony_ci }; 509e5c31af7Sopenharmony_ci VkSubresourceLayout layout; 510e5c31af7Sopenharmony_ci 511e5c31af7Sopenharmony_ci vkd.getImageSubresourceLayout(device, image, &subresource, &layout); 512e5c31af7Sopenharmony_ci 513e5c31af7Sopenharmony_ci for (deUint32 row = 0; row < planeH; ++row) 514e5c31af7Sopenharmony_ci { 515e5c31af7Sopenharmony_ci const size_t rowSize = planeSize / planeH; 516e5c31af7Sopenharmony_ci void* const dstPtr = ((deUint8*)allocation->getHostPtr()) + layout.offset + layout.rowPitch * row; 517e5c31af7Sopenharmony_ci const void* const srcPtr = ((const deUint8*)imageData.getPlanePtr(planeNdx)) + row * rowSize; 518e5c31af7Sopenharmony_ci 519e5c31af7Sopenharmony_ci deMemcpy(dstPtr, srcPtr, rowSize); 520e5c31af7Sopenharmony_ci } 521e5c31af7Sopenharmony_ci flushMappedMemoryRange(vkd, device, allocation->getMemory(), 0u, VK_WHOLE_SIZE); 522e5c31af7Sopenharmony_ci } 523e5c31af7Sopenharmony_ci 524e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, *cmdBuffer); 525e5c31af7Sopenharmony_ci 526e5c31af7Sopenharmony_ci { 527e5c31af7Sopenharmony_ci const VkImageMemoryBarrier postCopyBarrier = 528e5c31af7Sopenharmony_ci { 529e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 530e5c31af7Sopenharmony_ci DE_NULL, 531e5c31af7Sopenharmony_ci 0u, 532e5c31af7Sopenharmony_ci nextAccess, 533e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_PREINITIALIZED, 534e5c31af7Sopenharmony_ci finalLayout, 535e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 536e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 537e5c31af7Sopenharmony_ci image, 538e5c31af7Sopenharmony_ci { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, arrayLayer, 1u } 539e5c31af7Sopenharmony_ci }; 540e5c31af7Sopenharmony_ci 541e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 542e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT, 543e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 544e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 545e5c31af7Sopenharmony_ci 0u, 546e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 547e5c31af7Sopenharmony_ci 0u, 548e5c31af7Sopenharmony_ci (const VkBufferMemoryBarrier*)DE_NULL, 549e5c31af7Sopenharmony_ci 1u, 550e5c31af7Sopenharmony_ci &postCopyBarrier); 551e5c31af7Sopenharmony_ci } 552e5c31af7Sopenharmony_ci 553e5c31af7Sopenharmony_ci endCommandBuffer(vkd, *cmdBuffer); 554e5c31af7Sopenharmony_ci 555e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, *cmdBuffer); 556e5c31af7Sopenharmony_ci} 557e5c31af7Sopenharmony_ci 558e5c31af7Sopenharmony_civoid downloadImage (const DeviceInterface& vkd, 559e5c31af7Sopenharmony_ci VkDevice device, 560e5c31af7Sopenharmony_ci deUint32 queueFamilyNdx, 561e5c31af7Sopenharmony_ci Allocator& allocator, 562e5c31af7Sopenharmony_ci VkImage image, 563e5c31af7Sopenharmony_ci MultiPlaneImageData* imageData, 564e5c31af7Sopenharmony_ci VkAccessFlags prevAccess, 565e5c31af7Sopenharmony_ci VkImageLayout initialLayout, 566e5c31af7Sopenharmony_ci uint32_t baseArrayLayer) 567e5c31af7Sopenharmony_ci{ 568e5c31af7Sopenharmony_ci const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u); 569e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx)); 570e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 571e5c31af7Sopenharmony_ci vector<VkBufferSp> stagingBuffers; 572e5c31af7Sopenharmony_ci vector<AllocationSp> stagingMemory; 573e5c31af7Sopenharmony_ci 574e5c31af7Sopenharmony_ci const PlanarFormatDescription& formatDesc = imageData->getDescription(); 575e5c31af7Sopenharmony_ci 576e5c31af7Sopenharmony_ci allocateStagingBuffers(vkd, device, allocator, *imageData, &stagingBuffers, &stagingMemory); 577e5c31af7Sopenharmony_ci 578e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, *cmdBuffer); 579e5c31af7Sopenharmony_ci 580e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < imageData->getDescription().numPlanes; ++planeNdx) 581e5c31af7Sopenharmony_ci { 582e5c31af7Sopenharmony_ci const VkImageAspectFlagBits aspect = (formatDesc.numPlanes > 1) 583e5c31af7Sopenharmony_ci ? getPlaneAspect(planeNdx) 584e5c31af7Sopenharmony_ci : VK_IMAGE_ASPECT_COLOR_BIT; 585e5c31af7Sopenharmony_ci { 586e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyBarrier = 587e5c31af7Sopenharmony_ci { 588e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 589e5c31af7Sopenharmony_ci DE_NULL, 590e5c31af7Sopenharmony_ci prevAccess, 591e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_READ_BIT, 592e5c31af7Sopenharmony_ci initialLayout, 593e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 594e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 595e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 596e5c31af7Sopenharmony_ci image, 597e5c31af7Sopenharmony_ci { 598e5c31af7Sopenharmony_ci static_cast<vk::VkImageAspectFlags>(aspect), 599e5c31af7Sopenharmony_ci 0u, 600e5c31af7Sopenharmony_ci 1u, 601e5c31af7Sopenharmony_ci baseArrayLayer, 602e5c31af7Sopenharmony_ci 1u 603e5c31af7Sopenharmony_ci } 604e5c31af7Sopenharmony_ci }; 605e5c31af7Sopenharmony_ci 606e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 607e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 608e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT, 609e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 610e5c31af7Sopenharmony_ci 0u, 611e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 612e5c31af7Sopenharmony_ci 0u, 613e5c31af7Sopenharmony_ci (const VkBufferMemoryBarrier*)DE_NULL, 614e5c31af7Sopenharmony_ci 1u, 615e5c31af7Sopenharmony_ci &preCopyBarrier); 616e5c31af7Sopenharmony_ci } 617e5c31af7Sopenharmony_ci { 618e5c31af7Sopenharmony_ci const VkExtent3D imageExtent = makeExtent3D(imageData->getSize().x(), imageData->getSize().y(), 1u); 619e5c31af7Sopenharmony_ci const VkExtent3D planeExtent = getPlaneExtent(formatDesc, imageExtent, planeNdx, 0); 620e5c31af7Sopenharmony_ci const VkBufferImageCopy copy = 621e5c31af7Sopenharmony_ci { 622e5c31af7Sopenharmony_ci 0u, // bufferOffset 623e5c31af7Sopenharmony_ci 0u, // bufferRowLength 624e5c31af7Sopenharmony_ci 0u, // bufferImageHeight 625e5c31af7Sopenharmony_ci { (VkImageAspectFlags)aspect, 0u, baseArrayLayer, 1u }, 626e5c31af7Sopenharmony_ci makeOffset3D(0u, 0u, 0u), 627e5c31af7Sopenharmony_ci planeExtent 628e5c31af7Sopenharmony_ci }; 629e5c31af7Sopenharmony_ci 630e5c31af7Sopenharmony_ci vkd.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **stagingBuffers[planeNdx], 1u, ©); 631e5c31af7Sopenharmony_ci } 632e5c31af7Sopenharmony_ci { 633e5c31af7Sopenharmony_ci const VkBufferMemoryBarrier postCopyBarrier = 634e5c31af7Sopenharmony_ci { 635e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 636e5c31af7Sopenharmony_ci DE_NULL, 637e5c31af7Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT, 638e5c31af7Sopenharmony_ci VK_ACCESS_HOST_READ_BIT, 639e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 640e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 641e5c31af7Sopenharmony_ci **stagingBuffers[planeNdx], 642e5c31af7Sopenharmony_ci 0u, 643e5c31af7Sopenharmony_ci VK_WHOLE_SIZE 644e5c31af7Sopenharmony_ci }; 645e5c31af7Sopenharmony_ci 646e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 647e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_TRANSFER_BIT, 648e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT, 649e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 650e5c31af7Sopenharmony_ci 0u, 651e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 652e5c31af7Sopenharmony_ci 1u, 653e5c31af7Sopenharmony_ci &postCopyBarrier, 654e5c31af7Sopenharmony_ci 0u, 655e5c31af7Sopenharmony_ci (const VkImageMemoryBarrier*)DE_NULL); 656e5c31af7Sopenharmony_ci } 657e5c31af7Sopenharmony_ci } 658e5c31af7Sopenharmony_ci 659e5c31af7Sopenharmony_ci endCommandBuffer(vkd, *cmdBuffer); 660e5c31af7Sopenharmony_ci 661e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, *cmdBuffer); 662e5c31af7Sopenharmony_ci 663e5c31af7Sopenharmony_ci readStagingBuffers(imageData, vkd, device, stagingMemory); 664e5c31af7Sopenharmony_ci} 665e5c31af7Sopenharmony_ci 666e5c31af7Sopenharmony_civoid readImageMemory (const vk::DeviceInterface& vkd, 667e5c31af7Sopenharmony_ci vk::VkDevice device, 668e5c31af7Sopenharmony_ci deUint32 queueFamilyNdx, 669e5c31af7Sopenharmony_ci vk::VkImage image, 670e5c31af7Sopenharmony_ci const std::vector<de::SharedPtr<vk::Allocation> >& allocations, 671e5c31af7Sopenharmony_ci MultiPlaneImageData* imageData, 672e5c31af7Sopenharmony_ci vk::VkAccessFlags prevAccess, 673e5c31af7Sopenharmony_ci vk::VkImageLayout initialLayout) 674e5c31af7Sopenharmony_ci{ 675e5c31af7Sopenharmony_ci const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u); 676e5c31af7Sopenharmony_ci const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx)); 677e5c31af7Sopenharmony_ci const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 678e5c31af7Sopenharmony_ci const PlanarFormatDescription& formatDesc = imageData->getDescription(); 679e5c31af7Sopenharmony_ci 680e5c31af7Sopenharmony_ci beginCommandBuffer(vkd, *cmdBuffer); 681e5c31af7Sopenharmony_ci 682e5c31af7Sopenharmony_ci { 683e5c31af7Sopenharmony_ci const VkImageMemoryBarrier preCopyBarrier = 684e5c31af7Sopenharmony_ci { 685e5c31af7Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 686e5c31af7Sopenharmony_ci DE_NULL, 687e5c31af7Sopenharmony_ci prevAccess, 688e5c31af7Sopenharmony_ci vk::VK_ACCESS_HOST_READ_BIT, 689e5c31af7Sopenharmony_ci initialLayout, 690e5c31af7Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL, 691e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 692e5c31af7Sopenharmony_ci VK_QUEUE_FAMILY_IGNORED, 693e5c31af7Sopenharmony_ci image, 694e5c31af7Sopenharmony_ci { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } 695e5c31af7Sopenharmony_ci }; 696e5c31af7Sopenharmony_ci 697e5c31af7Sopenharmony_ci vkd.cmdPipelineBarrier(*cmdBuffer, 698e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 699e5c31af7Sopenharmony_ci (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT, 700e5c31af7Sopenharmony_ci (VkDependencyFlags)0u, 701e5c31af7Sopenharmony_ci 0u, 702e5c31af7Sopenharmony_ci (const VkMemoryBarrier*)DE_NULL, 703e5c31af7Sopenharmony_ci 0u, 704e5c31af7Sopenharmony_ci (const VkBufferMemoryBarrier*)DE_NULL, 705e5c31af7Sopenharmony_ci 1u, 706e5c31af7Sopenharmony_ci &preCopyBarrier); 707e5c31af7Sopenharmony_ci } 708e5c31af7Sopenharmony_ci 709e5c31af7Sopenharmony_ci endCommandBuffer(vkd, *cmdBuffer); 710e5c31af7Sopenharmony_ci 711e5c31af7Sopenharmony_ci submitCommandsAndWait(vkd, device, queue, *cmdBuffer); 712e5c31af7Sopenharmony_ci 713e5c31af7Sopenharmony_ci for (deUint32 planeNdx = 0; planeNdx < formatDesc.numPlanes; ++planeNdx) 714e5c31af7Sopenharmony_ci { 715e5c31af7Sopenharmony_ci const VkImageAspectFlagBits aspect = (formatDesc.numPlanes > 1) 716e5c31af7Sopenharmony_ci ? getPlaneAspect(planeNdx) 717e5c31af7Sopenharmony_ci : VK_IMAGE_ASPECT_COLOR_BIT; 718e5c31af7Sopenharmony_ci const de::SharedPtr<Allocation>& allocation = allocations.size() > 1 719e5c31af7Sopenharmony_ci ? allocations[planeNdx] 720e5c31af7Sopenharmony_ci : allocations[0]; 721e5c31af7Sopenharmony_ci const size_t planeSize = imageData->getPlaneSize(planeNdx); 722e5c31af7Sopenharmony_ci const deUint32 planeH = imageData->getSize().y() / formatDesc.planes[planeNdx].heightDivisor; 723e5c31af7Sopenharmony_ci const VkImageSubresource subresource = 724e5c31af7Sopenharmony_ci { 725e5c31af7Sopenharmony_ci static_cast<vk::VkImageAspectFlags>(aspect), 726e5c31af7Sopenharmony_ci 0u, 727e5c31af7Sopenharmony_ci 0u, 728e5c31af7Sopenharmony_ci }; 729e5c31af7Sopenharmony_ci VkSubresourceLayout layout; 730e5c31af7Sopenharmony_ci 731e5c31af7Sopenharmony_ci vkd.getImageSubresourceLayout(device, image, &subresource, &layout); 732e5c31af7Sopenharmony_ci 733e5c31af7Sopenharmony_ci invalidateMappedMemoryRange(vkd, device, allocation->getMemory(), 0u, VK_WHOLE_SIZE); 734e5c31af7Sopenharmony_ci 735e5c31af7Sopenharmony_ci for (deUint32 row = 0; row < planeH; ++row) 736e5c31af7Sopenharmony_ci { 737e5c31af7Sopenharmony_ci const size_t rowSize = planeSize / planeH; 738e5c31af7Sopenharmony_ci const void* const srcPtr = ((const deUint8*)allocation->getHostPtr()) + layout.offset + layout.rowPitch * row; 739e5c31af7Sopenharmony_ci void* const dstPtr = ((deUint8*)imageData->getPlanePtr(planeNdx)) + row * rowSize; 740e5c31af7Sopenharmony_ci 741e5c31af7Sopenharmony_ci deMemcpy(dstPtr, srcPtr, rowSize); 742e5c31af7Sopenharmony_ci } 743e5c31af7Sopenharmony_ci } 744e5c31af7Sopenharmony_ci} 745e5c31af7Sopenharmony_ci 746e5c31af7Sopenharmony_ci// ChannelAccess utilities 747e5c31af7Sopenharmony_cinamespace 748e5c31af7Sopenharmony_ci{ 749e5c31af7Sopenharmony_ci 750e5c31af7Sopenharmony_ci//! Extend < 32b signed integer to 32b 751e5c31af7Sopenharmony_ciinline deInt32 signExtend (deUint32 src, int bits) 752e5c31af7Sopenharmony_ci{ 753e5c31af7Sopenharmony_ci const deUint32 signBit = 1u << (bits-1); 754e5c31af7Sopenharmony_ci 755e5c31af7Sopenharmony_ci src |= ~((src & signBit) - 1); 756e5c31af7Sopenharmony_ci 757e5c31af7Sopenharmony_ci return (deInt32)src; 758e5c31af7Sopenharmony_ci} 759e5c31af7Sopenharmony_ci 760e5c31af7Sopenharmony_cideUint32 divRoundUp (deUint32 a, deUint32 b) 761e5c31af7Sopenharmony_ci{ 762e5c31af7Sopenharmony_ci if (a % b == 0) 763e5c31af7Sopenharmony_ci return a / b; 764e5c31af7Sopenharmony_ci else 765e5c31af7Sopenharmony_ci return (a / b) + 1; 766e5c31af7Sopenharmony_ci} 767e5c31af7Sopenharmony_ci 768e5c31af7Sopenharmony_ci// \todo Taken from tcuTexture.cpp 769e5c31af7Sopenharmony_ci// \todo [2011-09-21 pyry] Move to tcutil? 770e5c31af7Sopenharmony_citemplate <typename T> 771e5c31af7Sopenharmony_ciinline T convertSatRte (float f) 772e5c31af7Sopenharmony_ci{ 773e5c31af7Sopenharmony_ci // \note Doesn't work for 64-bit types 774e5c31af7Sopenharmony_ci DE_STATIC_ASSERT(sizeof(T) < sizeof(deUint64)); 775e5c31af7Sopenharmony_ci DE_STATIC_ASSERT((-3 % 2 != 0) && (-4 % 2 == 0)); 776e5c31af7Sopenharmony_ci 777e5c31af7Sopenharmony_ci deInt64 minVal = std::numeric_limits<T>::min(); 778e5c31af7Sopenharmony_ci deInt64 maxVal = std::numeric_limits<T>::max(); 779e5c31af7Sopenharmony_ci float q = deFloatFrac(f); 780e5c31af7Sopenharmony_ci deInt64 intVal = (deInt64)(f-q); 781e5c31af7Sopenharmony_ci 782e5c31af7Sopenharmony_ci // Rounding. 783e5c31af7Sopenharmony_ci if (q == 0.5f) 784e5c31af7Sopenharmony_ci { 785e5c31af7Sopenharmony_ci if (intVal % 2 != 0) 786e5c31af7Sopenharmony_ci intVal++; 787e5c31af7Sopenharmony_ci } 788e5c31af7Sopenharmony_ci else if (q > 0.5f) 789e5c31af7Sopenharmony_ci intVal++; 790e5c31af7Sopenharmony_ci // else Don't add anything 791e5c31af7Sopenharmony_ci 792e5c31af7Sopenharmony_ci // Saturate. 793e5c31af7Sopenharmony_ci intVal = de::max(minVal, de::min(maxVal, intVal)); 794e5c31af7Sopenharmony_ci 795e5c31af7Sopenharmony_ci return (T)intVal; 796e5c31af7Sopenharmony_ci} 797e5c31af7Sopenharmony_ci 798e5c31af7Sopenharmony_ci} // anonymous 799e5c31af7Sopenharmony_ci 800e5c31af7Sopenharmony_ciChannelAccess::ChannelAccess (tcu::TextureChannelClass channelClass, 801e5c31af7Sopenharmony_ci deUint8 channelSize, 802e5c31af7Sopenharmony_ci const tcu::IVec3& size, 803e5c31af7Sopenharmony_ci const tcu::IVec3& bitPitch, 804e5c31af7Sopenharmony_ci void* data, 805e5c31af7Sopenharmony_ci deUint32 bitOffset) 806e5c31af7Sopenharmony_ci : m_channelClass (channelClass) 807e5c31af7Sopenharmony_ci , m_channelSize (channelSize) 808e5c31af7Sopenharmony_ci , m_size (size) 809e5c31af7Sopenharmony_ci , m_bitPitch (bitPitch) 810e5c31af7Sopenharmony_ci , m_data ((deUint8*)data + (bitOffset / 8)) 811e5c31af7Sopenharmony_ci , m_bitOffset (bitOffset % 8) 812e5c31af7Sopenharmony_ci{ 813e5c31af7Sopenharmony_ci} 814e5c31af7Sopenharmony_ci 815e5c31af7Sopenharmony_cideUint32 ChannelAccess::getChannelUint (const tcu::IVec3& pos) const 816e5c31af7Sopenharmony_ci{ 817e5c31af7Sopenharmony_ci DE_ASSERT(pos[0] < m_size[0]); 818e5c31af7Sopenharmony_ci DE_ASSERT(pos[1] < m_size[1]); 819e5c31af7Sopenharmony_ci DE_ASSERT(pos[2] < m_size[2]); 820e5c31af7Sopenharmony_ci 821e5c31af7Sopenharmony_ci const deInt32 bitOffset (m_bitOffset + tcu::dot(m_bitPitch, pos)); 822e5c31af7Sopenharmony_ci const deUint8* const firstByte = ((const deUint8*)m_data) + (bitOffset / 8); 823e5c31af7Sopenharmony_ci const deUint32 byteCount = divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u); 824e5c31af7Sopenharmony_ci const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u); 825e5c31af7Sopenharmony_ci const deUint32 offset = bitOffset % 8; 826e5c31af7Sopenharmony_ci deUint32 bits = 0u; 827e5c31af7Sopenharmony_ci 828e5c31af7Sopenharmony_ci deMemcpy(&bits, firstByte, byteCount); 829e5c31af7Sopenharmony_ci 830e5c31af7Sopenharmony_ci return (bits >> offset) & mask; 831e5c31af7Sopenharmony_ci} 832e5c31af7Sopenharmony_ci 833e5c31af7Sopenharmony_civoid ChannelAccess::setChannel (const tcu::IVec3& pos, deUint32 x) 834e5c31af7Sopenharmony_ci{ 835e5c31af7Sopenharmony_ci DE_ASSERT(pos[0] < m_size[0]); 836e5c31af7Sopenharmony_ci DE_ASSERT(pos[1] < m_size[1]); 837e5c31af7Sopenharmony_ci DE_ASSERT(pos[2] < m_size[2]); 838e5c31af7Sopenharmony_ci 839e5c31af7Sopenharmony_ci const deInt32 bitOffset (m_bitOffset + tcu::dot(m_bitPitch, pos)); 840e5c31af7Sopenharmony_ci deUint8* const firstByte = ((deUint8*)m_data) + (bitOffset / 8); 841e5c31af7Sopenharmony_ci const deUint32 byteCount = divRoundUp((bitOffset + m_channelSize) - 8u * (bitOffset / 8u), 8u); 842e5c31af7Sopenharmony_ci const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u); 843e5c31af7Sopenharmony_ci const deUint32 offset = bitOffset % 8; 844e5c31af7Sopenharmony_ci 845e5c31af7Sopenharmony_ci const deUint32 bits = (x & mask) << offset; 846e5c31af7Sopenharmony_ci deUint32 oldBits = 0; 847e5c31af7Sopenharmony_ci 848e5c31af7Sopenharmony_ci deMemcpy(&oldBits, firstByte, byteCount); 849e5c31af7Sopenharmony_ci 850e5c31af7Sopenharmony_ci { 851e5c31af7Sopenharmony_ci const deUint32 newBits = bits | (oldBits & (~(mask << offset))); 852e5c31af7Sopenharmony_ci 853e5c31af7Sopenharmony_ci deMemcpy(firstByte, &newBits, byteCount); 854e5c31af7Sopenharmony_ci } 855e5c31af7Sopenharmony_ci} 856e5c31af7Sopenharmony_ci 857e5c31af7Sopenharmony_cifloat ChannelAccess::getChannel (const tcu::IVec3& pos) const 858e5c31af7Sopenharmony_ci{ 859e5c31af7Sopenharmony_ci const deUint32 bits (getChannelUint(pos)); 860e5c31af7Sopenharmony_ci 861e5c31af7Sopenharmony_ci switch (m_channelClass) 862e5c31af7Sopenharmony_ci { 863e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 864e5c31af7Sopenharmony_ci return (float)bits / (float)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u)); 865e5c31af7Sopenharmony_ci 866e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 867e5c31af7Sopenharmony_ci return (float)bits; 868e5c31af7Sopenharmony_ci 869e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 870e5c31af7Sopenharmony_ci return de::max(-1.0f, (float)signExtend(bits, m_channelSize) / (float)((0x1u << (m_channelSize - 1u)) - 1u)); 871e5c31af7Sopenharmony_ci 872e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 873e5c31af7Sopenharmony_ci return (float)signExtend(bits, m_channelSize); 874e5c31af7Sopenharmony_ci 875e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 876e5c31af7Sopenharmony_ci if (m_channelSize == 32) 877e5c31af7Sopenharmony_ci return tcu::Float32(bits).asFloat(); 878e5c31af7Sopenharmony_ci else 879e5c31af7Sopenharmony_ci { 880e5c31af7Sopenharmony_ci DE_FATAL("Float type not supported"); 881e5c31af7Sopenharmony_ci return -1.0f; 882e5c31af7Sopenharmony_ci } 883e5c31af7Sopenharmony_ci 884e5c31af7Sopenharmony_ci default: 885e5c31af7Sopenharmony_ci DE_FATAL("Unknown texture channel class"); 886e5c31af7Sopenharmony_ci return -1.0f; 887e5c31af7Sopenharmony_ci } 888e5c31af7Sopenharmony_ci} 889e5c31af7Sopenharmony_ci 890e5c31af7Sopenharmony_citcu::Interval ChannelAccess::getChannel (const tcu::FloatFormat& conversionFormat, 891e5c31af7Sopenharmony_ci const tcu::IVec3& pos) const 892e5c31af7Sopenharmony_ci{ 893e5c31af7Sopenharmony_ci const deUint32 bits (getChannelUint(pos)); 894e5c31af7Sopenharmony_ci 895e5c31af7Sopenharmony_ci switch (m_channelClass) 896e5c31af7Sopenharmony_ci { 897e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 898e5c31af7Sopenharmony_ci return conversionFormat.roundOut(conversionFormat.roundOut((double)bits, false) 899e5c31af7Sopenharmony_ci / conversionFormat.roundOut((double)(m_channelSize == 32 ? ~0x0u : ((0x1u << m_channelSize) - 1u)), false), false); 900e5c31af7Sopenharmony_ci 901e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 902e5c31af7Sopenharmony_ci return conversionFormat.roundOut((double)bits, false); 903e5c31af7Sopenharmony_ci 904e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 905e5c31af7Sopenharmony_ci { 906e5c31af7Sopenharmony_ci const tcu::Interval result (conversionFormat.roundOut(conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false) 907e5c31af7Sopenharmony_ci / conversionFormat.roundOut((double)((0x1u << (m_channelSize - 1u)) - 1u), false), false)); 908e5c31af7Sopenharmony_ci 909e5c31af7Sopenharmony_ci return tcu::Interval(de::max(-1.0, result.lo()), de::max(-1.0, result.hi())); 910e5c31af7Sopenharmony_ci } 911e5c31af7Sopenharmony_ci 912e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 913e5c31af7Sopenharmony_ci return conversionFormat.roundOut((double)signExtend(bits, m_channelSize), false); 914e5c31af7Sopenharmony_ci 915e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 916e5c31af7Sopenharmony_ci if (m_channelSize == 32) 917e5c31af7Sopenharmony_ci return conversionFormat.roundOut(tcu::Float32(bits).asFloat(), false); 918e5c31af7Sopenharmony_ci else 919e5c31af7Sopenharmony_ci { 920e5c31af7Sopenharmony_ci DE_FATAL("Float type not supported"); 921e5c31af7Sopenharmony_ci return tcu::Interval(); 922e5c31af7Sopenharmony_ci } 923e5c31af7Sopenharmony_ci 924e5c31af7Sopenharmony_ci default: 925e5c31af7Sopenharmony_ci DE_FATAL("Unknown texture channel class"); 926e5c31af7Sopenharmony_ci return tcu::Interval(); 927e5c31af7Sopenharmony_ci } 928e5c31af7Sopenharmony_ci} 929e5c31af7Sopenharmony_ci 930e5c31af7Sopenharmony_civoid ChannelAccess::setChannel (const tcu::IVec3& pos, float x) 931e5c31af7Sopenharmony_ci{ 932e5c31af7Sopenharmony_ci DE_ASSERT(pos[0] < m_size[0]); 933e5c31af7Sopenharmony_ci DE_ASSERT(pos[1] < m_size[1]); 934e5c31af7Sopenharmony_ci DE_ASSERT(pos[2] < m_size[2]); 935e5c31af7Sopenharmony_ci 936e5c31af7Sopenharmony_ci const deUint32 mask (m_channelSize == 32u ? ~0x0u : (0x1u << m_channelSize) - 1u); 937e5c31af7Sopenharmony_ci 938e5c31af7Sopenharmony_ci switch (m_channelClass) 939e5c31af7Sopenharmony_ci { 940e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: 941e5c31af7Sopenharmony_ci { 942e5c31af7Sopenharmony_ci const deUint32 maxValue (mask); 943e5c31af7Sopenharmony_ci const deUint32 value (de::min(maxValue, (deUint32)convertSatRte<deUint32>(x * (float)maxValue))); 944e5c31af7Sopenharmony_ci setChannel(pos, value); 945e5c31af7Sopenharmony_ci break; 946e5c31af7Sopenharmony_ci } 947e5c31af7Sopenharmony_ci 948e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: 949e5c31af7Sopenharmony_ci { 950e5c31af7Sopenharmony_ci const deInt32 range ((0x1u << (m_channelSize - 1u)) - 1u); 951e5c31af7Sopenharmony_ci const deUint32 value ((deUint32)de::clamp<deInt32>(convertSatRte<deInt32>(x * (float)range), -range, range)); 952e5c31af7Sopenharmony_ci setChannel(pos, value); 953e5c31af7Sopenharmony_ci break; 954e5c31af7Sopenharmony_ci } 955e5c31af7Sopenharmony_ci 956e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER: 957e5c31af7Sopenharmony_ci { 958e5c31af7Sopenharmony_ci const deUint32 maxValue (mask); 959e5c31af7Sopenharmony_ci const deUint32 value (de::min(maxValue, (deUint32)x)); 960e5c31af7Sopenharmony_ci setChannel(pos, value); 961e5c31af7Sopenharmony_ci break; 962e5c31af7Sopenharmony_ci } 963e5c31af7Sopenharmony_ci 964e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER: 965e5c31af7Sopenharmony_ci { 966e5c31af7Sopenharmony_ci const deInt32 minValue (-(deInt32)(1u << (m_channelSize - 1u))); 967e5c31af7Sopenharmony_ci const deInt32 maxValue ((deInt32)((1u << (m_channelSize - 1u)) - 1u)); 968e5c31af7Sopenharmony_ci const deUint32 value ((deUint32)de::clamp((deInt32)x, minValue, maxValue)); 969e5c31af7Sopenharmony_ci setChannel(pos, value); 970e5c31af7Sopenharmony_ci break; 971e5c31af7Sopenharmony_ci } 972e5c31af7Sopenharmony_ci 973e5c31af7Sopenharmony_ci case tcu::TEXTURECHANNELCLASS_FLOATING_POINT: 974e5c31af7Sopenharmony_ci { 975e5c31af7Sopenharmony_ci if (m_channelSize == 32) 976e5c31af7Sopenharmony_ci { 977e5c31af7Sopenharmony_ci const deUint32 value = tcu::Float32(x).bits(); 978e5c31af7Sopenharmony_ci setChannel(pos, value); 979e5c31af7Sopenharmony_ci } 980e5c31af7Sopenharmony_ci else 981e5c31af7Sopenharmony_ci DE_FATAL("Float type not supported"); 982e5c31af7Sopenharmony_ci break; 983e5c31af7Sopenharmony_ci } 984e5c31af7Sopenharmony_ci 985e5c31af7Sopenharmony_ci default: 986e5c31af7Sopenharmony_ci DE_FATAL("Unknown texture channel class"); 987e5c31af7Sopenharmony_ci } 988e5c31af7Sopenharmony_ci} 989e5c31af7Sopenharmony_ci 990e5c31af7Sopenharmony_ciChannelAccess getChannelAccess (MultiPlaneImageData& data, 991e5c31af7Sopenharmony_ci const vk::PlanarFormatDescription& formatInfo, 992e5c31af7Sopenharmony_ci const UVec2& size, 993e5c31af7Sopenharmony_ci int channelNdx) 994e5c31af7Sopenharmony_ci{ 995e5c31af7Sopenharmony_ci DE_ASSERT(formatInfo.hasChannelNdx(channelNdx)); 996e5c31af7Sopenharmony_ci 997e5c31af7Sopenharmony_ci const deUint32 planeNdx = formatInfo.channels[channelNdx].planeNdx; 998e5c31af7Sopenharmony_ci const deUint32 valueOffsetBits = formatInfo.channels[channelNdx].offsetBits; 999e5c31af7Sopenharmony_ci const deUint32 pixelStrideBytes = formatInfo.channels[channelNdx].strideBytes; 1000e5c31af7Sopenharmony_ci const deUint32 pixelStrideBits = pixelStrideBytes * 8; 1001e5c31af7Sopenharmony_ci const deUint8 sizeBits = formatInfo.channels[channelNdx].sizeBits; 1002e5c31af7Sopenharmony_ci 1003e5c31af7Sopenharmony_ci DE_ASSERT(size.x() % (formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor) == 0); 1004e5c31af7Sopenharmony_ci DE_ASSERT(size.y() % (formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor) == 0); 1005e5c31af7Sopenharmony_ci 1006e5c31af7Sopenharmony_ci deUint32 accessWidth = size.x() / ( formatInfo.blockWidth * formatInfo.planes[planeNdx].widthDivisor ); 1007e5c31af7Sopenharmony_ci const deUint32 accessHeight = size.y() / ( formatInfo.blockHeight * formatInfo.planes[planeNdx].heightDivisor ); 1008e5c31af7Sopenharmony_ci const deUint32 elementSizeBytes = formatInfo.planes[planeNdx].elementSizeBytes; 1009e5c31af7Sopenharmony_ci const deUint32 rowPitch = formatInfo.planes[planeNdx].elementSizeBytes * accessWidth; 1010e5c31af7Sopenharmony_ci const deUint32 rowPitchBits = rowPitch * 8; 1011e5c31af7Sopenharmony_ci 1012e5c31af7Sopenharmony_ci if (pixelStrideBytes != elementSizeBytes) 1013e5c31af7Sopenharmony_ci { 1014e5c31af7Sopenharmony_ci DE_ASSERT(elementSizeBytes % pixelStrideBytes == 0); 1015e5c31af7Sopenharmony_ci accessWidth *= elementSizeBytes/pixelStrideBytes; 1016e5c31af7Sopenharmony_ci } 1017e5c31af7Sopenharmony_ci 1018e5c31af7Sopenharmony_ci return ChannelAccess((tcu::TextureChannelClass)formatInfo.channels[channelNdx].type, sizeBits, tcu::IVec3(accessWidth, accessHeight, 1u), tcu::IVec3((int)pixelStrideBits, (int)rowPitchBits, 0), data.getPlanePtr(planeNdx), (deUint32)valueOffsetBits); 1019e5c31af7Sopenharmony_ci} 1020e5c31af7Sopenharmony_ci 1021e5c31af7Sopenharmony_cibool isXChromaSubsampled (vk::VkFormat format) 1022e5c31af7Sopenharmony_ci{ 1023e5c31af7Sopenharmony_ci switch (format) 1024e5c31af7Sopenharmony_ci { 1025e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8B8G8R8_422_UNORM: 1026e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B8G8R8G8_422_UNORM: 1027e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 1028e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1029e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 1030e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 1031e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 1032e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 1033e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 1034e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 1035e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 1036e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 1037e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 1038e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 1039e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 1040e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 1041e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 1042e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 1043e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16B16G16R16_422_UNORM: 1044e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B16G16R16G16_422_UNORM: 1045e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 1046e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 1047e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 1048e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 1049e5c31af7Sopenharmony_ci return true; 1050e5c31af7Sopenharmony_ci 1051e5c31af7Sopenharmony_ci default: 1052e5c31af7Sopenharmony_ci return false; 1053e5c31af7Sopenharmony_ci } 1054e5c31af7Sopenharmony_ci} 1055e5c31af7Sopenharmony_ci 1056e5c31af7Sopenharmony_cibool isYChromaSubsampled (vk::VkFormat format) 1057e5c31af7Sopenharmony_ci{ 1058e5c31af7Sopenharmony_ci switch (format) 1059e5c31af7Sopenharmony_ci { 1060e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 1061e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1062e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 1063e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 1064e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 1065e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 1066e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 1067e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 1068e5c31af7Sopenharmony_ci return true; 1069e5c31af7Sopenharmony_ci 1070e5c31af7Sopenharmony_ci default: 1071e5c31af7Sopenharmony_ci return false; 1072e5c31af7Sopenharmony_ci } 1073e5c31af7Sopenharmony_ci} 1074e5c31af7Sopenharmony_ci 1075e5c31af7Sopenharmony_cibool areLsb6BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat) 1076e5c31af7Sopenharmony_ci{ 1077e5c31af7Sopenharmony_ci if ((srcFormat == vk::VK_FORMAT_R10X6_UNORM_PACK16) || 1078e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R10X6_UNORM_PACK16) || 1079e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) || 1080e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16) || 1081e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) || 1082e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) || 1083e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) || 1084e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16) || 1085e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) || 1086e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16) || 1087e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) || 1088e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16) || 1089e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) || 1090e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16) || 1091e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) || 1092e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16) || 1093e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) || 1094e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16) || 1095e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16) || 1096e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16)) 1097e5c31af7Sopenharmony_ci { 1098e5c31af7Sopenharmony_ci return true; 1099e5c31af7Sopenharmony_ci } 1100e5c31af7Sopenharmony_ci 1101e5c31af7Sopenharmony_ci return false; 1102e5c31af7Sopenharmony_ci} 1103e5c31af7Sopenharmony_ci 1104e5c31af7Sopenharmony_cibool areLsb4BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat) 1105e5c31af7Sopenharmony_ci{ 1106e5c31af7Sopenharmony_ci if ((srcFormat == vk::VK_FORMAT_R12X4_UNORM_PACK16) || 1107e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R12X4_UNORM_PACK16) || 1108e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) || 1109e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16) || 1110e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) || 1111e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16) || 1112e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) || 1113e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16) || 1114e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) || 1115e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16) || 1116e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) || 1117e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16) || 1118e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) || 1119e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16) || 1120e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) || 1121e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16) || 1122e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) || 1123e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16) || 1124e5c31af7Sopenharmony_ci (srcFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16) || 1125e5c31af7Sopenharmony_ci (dstFormat == vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16)) 1126e5c31af7Sopenharmony_ci { 1127e5c31af7Sopenharmony_ci return true; 1128e5c31af7Sopenharmony_ci } 1129e5c31af7Sopenharmony_ci 1130e5c31af7Sopenharmony_ci return false; 1131e5c31af7Sopenharmony_ci} 1132e5c31af7Sopenharmony_ci 1133e5c31af7Sopenharmony_ci// \note Used for range expansion 1134e5c31af7Sopenharmony_citcu::UVec4 getYCbCrBitDepth (vk::VkFormat format) 1135e5c31af7Sopenharmony_ci{ 1136e5c31af7Sopenharmony_ci switch (format) 1137e5c31af7Sopenharmony_ci { 1138e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8B8G8R8_422_UNORM: 1139e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B8G8R8G8_422_UNORM: 1140e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 1141e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1142e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 1143e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 1144e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 1145e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: 1146e5c31af7Sopenharmony_ci return tcu::UVec4(8, 8, 8, 0); 1147e5c31af7Sopenharmony_ci 1148e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6_UNORM_PACK16: 1149e5c31af7Sopenharmony_ci return tcu::UVec4(10, 0, 0, 0); 1150e5c31af7Sopenharmony_ci 1151e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 1152e5c31af7Sopenharmony_ci return tcu::UVec4(10, 10, 0, 0); 1153e5c31af7Sopenharmony_ci 1154e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 1155e5c31af7Sopenharmony_ci return tcu::UVec4(10, 10, 10, 10); 1156e5c31af7Sopenharmony_ci 1157e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 1158e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 1159e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 1160e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 1161e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 1162e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 1163e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 1164e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT: 1165e5c31af7Sopenharmony_ci return tcu::UVec4(10, 10, 10, 0); 1166e5c31af7Sopenharmony_ci 1167e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4_UNORM_PACK16: 1168e5c31af7Sopenharmony_ci return tcu::UVec4(12, 0, 0, 0); 1169e5c31af7Sopenharmony_ci 1170e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 1171e5c31af7Sopenharmony_ci return tcu::UVec4(12, 12, 0, 0); 1172e5c31af7Sopenharmony_ci 1173e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 1174e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 1175e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 1176e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 1177e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 1178e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 1179e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 1180e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 1181e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT: 1182e5c31af7Sopenharmony_ci return tcu::UVec4(12, 12, 12, 12); 1183e5c31af7Sopenharmony_ci 1184e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16B16G16R16_422_UNORM: 1185e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B16G16R16G16_422_UNORM: 1186e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 1187e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 1188e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 1189e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 1190e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 1191e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: 1192e5c31af7Sopenharmony_ci return tcu::UVec4(16, 16, 16, 0); 1193e5c31af7Sopenharmony_ci 1194e5c31af7Sopenharmony_ci default: 1195e5c31af7Sopenharmony_ci return tcu::getTextureFormatBitDepth(vk::mapVkFormat(format)).cast<deUint32>(); 1196e5c31af7Sopenharmony_ci } 1197e5c31af7Sopenharmony_ci} 1198e5c31af7Sopenharmony_ci 1199e5c31af7Sopenharmony_cistd::vector<tcu::FloatFormat> getPrecision (VkFormat format) 1200e5c31af7Sopenharmony_ci{ 1201e5c31af7Sopenharmony_ci std::vector<FloatFormat> floatFormats; 1202e5c31af7Sopenharmony_ci UVec4 channelDepth = getYCbCrBitDepth (format); 1203e5c31af7Sopenharmony_ci 1204e5c31af7Sopenharmony_ci for (deUint32 channelIdx = 0; channelIdx < 4; channelIdx++) 1205e5c31af7Sopenharmony_ci floatFormats.push_back(tcu::FloatFormat(0, 0, channelDepth[channelIdx], false, tcu::YES)); 1206e5c31af7Sopenharmony_ci 1207e5c31af7Sopenharmony_ci return floatFormats; 1208e5c31af7Sopenharmony_ci} 1209e5c31af7Sopenharmony_ci 1210e5c31af7Sopenharmony_cideUint32 getYCbCrFormatChannelCount (vk::VkFormat format) 1211e5c31af7Sopenharmony_ci{ 1212e5c31af7Sopenharmony_ci switch (format) 1213e5c31af7Sopenharmony_ci { 1214e5c31af7Sopenharmony_ci case vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16: 1215e5c31af7Sopenharmony_ci case vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32: 1216e5c31af7Sopenharmony_ci case vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32: 1217e5c31af7Sopenharmony_ci case vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32: 1218e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16: 1219e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16: 1220e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B8G8R8A8_UNORM: 1221e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: 1222e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: 1223e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16G16B16A16_UNORM: 1224e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16: 1225e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16: 1226e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R8G8B8A8_UNORM: 1227e5c31af7Sopenharmony_ci return 4; 1228e5c31af7Sopenharmony_ci 1229e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: 1230e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: 1231e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B16G16R16G16_422_UNORM: 1232e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B5G6R5_UNORM_PACK16: 1233e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B8G8R8G8_422_UNORM: 1234e5c31af7Sopenharmony_ci case vk::VK_FORMAT_B8G8R8_UNORM: 1235e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: 1236e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: 1237e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: 1238e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16_EXT: 1239e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: 1240e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: 1241e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: 1242e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: 1243e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: 1244e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: 1245e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16_EXT: 1246e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: 1247e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: 1248e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: 1249e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16B16G16R16_422_UNORM: 1250e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: 1251e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: 1252e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT: 1253e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: 1254e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: 1255e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: 1256e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8B8G8R8_422_UNORM: 1257e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: 1258e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: 1259e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT: 1260e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: 1261e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: 1262e5c31af7Sopenharmony_ci case vk::VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: 1263e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R16G16B16_UNORM: 1264e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R5G6B5_UNORM_PACK16: 1265e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R8G8B8_UNORM: 1266e5c31af7Sopenharmony_ci return 3; 1267e5c31af7Sopenharmony_ci 1268e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6G10X6_UNORM_2PACK16: 1269e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4G12X4_UNORM_2PACK16: 1270e5c31af7Sopenharmony_ci return 2; 1271e5c31af7Sopenharmony_ci 1272e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R10X6_UNORM_PACK16: 1273e5c31af7Sopenharmony_ci case vk::VK_FORMAT_R12X4_UNORM_PACK16: 1274e5c31af7Sopenharmony_ci return 1; 1275e5c31af7Sopenharmony_ci 1276e5c31af7Sopenharmony_ci default: 1277e5c31af7Sopenharmony_ci DE_FATAL("Unknown number of channels"); 1278e5c31af7Sopenharmony_ci return -1; 1279e5c31af7Sopenharmony_ci } 1280e5c31af7Sopenharmony_ci} 1281e5c31af7Sopenharmony_ci 1282e5c31af7Sopenharmony_ci// YCbCr color conversion utilities 1283e5c31af7Sopenharmony_cinamespace 1284e5c31af7Sopenharmony_ci{ 1285e5c31af7Sopenharmony_ci 1286e5c31af7Sopenharmony_citcu::Interval rangeExpandChroma (vk::VkSamplerYcbcrRange range, 1287e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1288e5c31af7Sopenharmony_ci const deUint32 bits, 1289e5c31af7Sopenharmony_ci const tcu::Interval& sample) 1290e5c31af7Sopenharmony_ci{ 1291e5c31af7Sopenharmony_ci const deUint32 values (0x1u << bits); 1292e5c31af7Sopenharmony_ci 1293e5c31af7Sopenharmony_ci switch (range) 1294e5c31af7Sopenharmony_ci { 1295e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL: 1296e5c31af7Sopenharmony_ci return conversionFormat.roundOut(sample - conversionFormat.roundOut(tcu::Interval((double)(0x1u << (bits - 1u)) / (double)((0x1u << bits) - 1u)), false), false); 1297e5c31af7Sopenharmony_ci 1298e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW: 1299e5c31af7Sopenharmony_ci { 1300e5c31af7Sopenharmony_ci const tcu::Interval a (conversionFormat.roundOut(sample * tcu::Interval((double)(values - 1u)), false)); 1301e5c31af7Sopenharmony_ci const tcu::Interval dividend (conversionFormat.roundOut(a - tcu::Interval((double)(128u * (0x1u << (bits - 8u)))), false)); 1302e5c31af7Sopenharmony_ci const tcu::Interval divisor ((double)(224u * (0x1u << (bits - 8u)))); 1303e5c31af7Sopenharmony_ci const tcu::Interval result (conversionFormat.roundOut(dividend / divisor, false)); 1304e5c31af7Sopenharmony_ci 1305e5c31af7Sopenharmony_ci return result; 1306e5c31af7Sopenharmony_ci } 1307e5c31af7Sopenharmony_ci 1308e5c31af7Sopenharmony_ci default: 1309e5c31af7Sopenharmony_ci DE_FATAL("Unknown YCbCrRange"); 1310e5c31af7Sopenharmony_ci return tcu::Interval(); 1311e5c31af7Sopenharmony_ci } 1312e5c31af7Sopenharmony_ci} 1313e5c31af7Sopenharmony_ci 1314e5c31af7Sopenharmony_citcu::Interval rangeExpandLuma (vk::VkSamplerYcbcrRange range, 1315e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1316e5c31af7Sopenharmony_ci const deUint32 bits, 1317e5c31af7Sopenharmony_ci const tcu::Interval& sample) 1318e5c31af7Sopenharmony_ci{ 1319e5c31af7Sopenharmony_ci const deUint32 values (0x1u << bits); 1320e5c31af7Sopenharmony_ci 1321e5c31af7Sopenharmony_ci switch (range) 1322e5c31af7Sopenharmony_ci { 1323e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_RANGE_ITU_FULL: 1324e5c31af7Sopenharmony_ci return conversionFormat.roundOut(sample, false); 1325e5c31af7Sopenharmony_ci 1326e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_RANGE_ITU_NARROW: 1327e5c31af7Sopenharmony_ci { 1328e5c31af7Sopenharmony_ci const tcu::Interval a (conversionFormat.roundOut(sample * tcu::Interval((double)(values - 1u)), false)); 1329e5c31af7Sopenharmony_ci const tcu::Interval dividend (conversionFormat.roundOut(a - tcu::Interval((double)(16u * (0x1u << (bits - 8u)))), false)); 1330e5c31af7Sopenharmony_ci const tcu::Interval divisor ((double)(219u * (0x1u << (bits - 8u)))); 1331e5c31af7Sopenharmony_ci const tcu::Interval result (conversionFormat.roundOut(dividend / divisor, false)); 1332e5c31af7Sopenharmony_ci 1333e5c31af7Sopenharmony_ci return result; 1334e5c31af7Sopenharmony_ci } 1335e5c31af7Sopenharmony_ci 1336e5c31af7Sopenharmony_ci default: 1337e5c31af7Sopenharmony_ci DE_FATAL("Unknown YCbCrRange"); 1338e5c31af7Sopenharmony_ci return tcu::Interval(); 1339e5c31af7Sopenharmony_ci } 1340e5c31af7Sopenharmony_ci} 1341e5c31af7Sopenharmony_ci 1342e5c31af7Sopenharmony_citcu::Interval clampMaybe (const tcu::Interval& x, 1343e5c31af7Sopenharmony_ci double min, 1344e5c31af7Sopenharmony_ci double max) 1345e5c31af7Sopenharmony_ci{ 1346e5c31af7Sopenharmony_ci tcu::Interval result = x; 1347e5c31af7Sopenharmony_ci 1348e5c31af7Sopenharmony_ci DE_ASSERT(min <= max); 1349e5c31af7Sopenharmony_ci 1350e5c31af7Sopenharmony_ci if (x.lo() < min) 1351e5c31af7Sopenharmony_ci result = result | tcu::Interval(min); 1352e5c31af7Sopenharmony_ci 1353e5c31af7Sopenharmony_ci if (x.hi() > max) 1354e5c31af7Sopenharmony_ci result = result | tcu::Interval(max); 1355e5c31af7Sopenharmony_ci 1356e5c31af7Sopenharmony_ci return result; 1357e5c31af7Sopenharmony_ci} 1358e5c31af7Sopenharmony_ci 1359e5c31af7Sopenharmony_civoid convertColor (vk::VkSamplerYcbcrModelConversion colorModel, 1360e5c31af7Sopenharmony_ci vk::VkSamplerYcbcrRange range, 1361e5c31af7Sopenharmony_ci const vector<tcu::FloatFormat>& conversionFormat, 1362e5c31af7Sopenharmony_ci const tcu::UVec4& bitDepth, 1363e5c31af7Sopenharmony_ci const tcu::Interval input[4], 1364e5c31af7Sopenharmony_ci tcu::Interval output[4]) 1365e5c31af7Sopenharmony_ci{ 1366e5c31af7Sopenharmony_ci switch (colorModel) 1367e5c31af7Sopenharmony_ci { 1368e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY: 1369e5c31af7Sopenharmony_ci { 1370e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < 4; ndx++) 1371e5c31af7Sopenharmony_ci output[ndx] = input[ndx]; 1372e5c31af7Sopenharmony_ci break; 1373e5c31af7Sopenharmony_ci } 1374e5c31af7Sopenharmony_ci 1375e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY: 1376e5c31af7Sopenharmony_ci { 1377e5c31af7Sopenharmony_ci output[0] = clampMaybe(rangeExpandChroma(range, conversionFormat[0], bitDepth[0], input[0]), -0.5, 0.5); 1378e5c31af7Sopenharmony_ci output[1] = clampMaybe(rangeExpandLuma(range, conversionFormat[1], bitDepth[1], input[1]), 0.0, 1.0); 1379e5c31af7Sopenharmony_ci output[2] = clampMaybe(rangeExpandChroma(range, conversionFormat[2], bitDepth[2], input[2]), -0.5, 0.5); 1380e5c31af7Sopenharmony_ci output[3] = input[3]; 1381e5c31af7Sopenharmony_ci break; 1382e5c31af7Sopenharmony_ci } 1383e5c31af7Sopenharmony_ci 1384e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601: 1385e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709: 1386e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_2020: 1387e5c31af7Sopenharmony_ci { 1388e5c31af7Sopenharmony_ci const tcu::Interval y (rangeExpandLuma(range, conversionFormat[1], bitDepth[1], input[1])); 1389e5c31af7Sopenharmony_ci const tcu::Interval cr (rangeExpandChroma(range, conversionFormat[0], bitDepth[0], input[0])); 1390e5c31af7Sopenharmony_ci const tcu::Interval cb (rangeExpandChroma(range, conversionFormat[2], bitDepth[2], input[2])); 1391e5c31af7Sopenharmony_ci 1392e5c31af7Sopenharmony_ci const tcu::Interval yClamped (clampMaybe(y, 0.0, 1.0)); 1393e5c31af7Sopenharmony_ci const tcu::Interval crClamped (clampMaybe(cr, -0.5, 0.5)); 1394e5c31af7Sopenharmony_ci const tcu::Interval cbClamped (clampMaybe(cb, -0.5, 0.5)); 1395e5c31af7Sopenharmony_ci 1396e5c31af7Sopenharmony_ci if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_601) 1397e5c31af7Sopenharmony_ci { 1398e5c31af7Sopenharmony_ci output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.402 * crClamped, false), false); 1399e5c31af7Sopenharmony_ci output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut((0.202008 / 0.587) * cbClamped, false), false) - conversionFormat[1].roundOut((0.419198 / 0.587) * crClamped, false), false); 1400e5c31af7Sopenharmony_ci output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.772 * cbClamped, false), false); 1401e5c31af7Sopenharmony_ci } 1402e5c31af7Sopenharmony_ci else if (colorModel == vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_709) 1403e5c31af7Sopenharmony_ci { 1404e5c31af7Sopenharmony_ci output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.5748 * crClamped, false), false); 1405e5c31af7Sopenharmony_ci output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut((0.13397432 / 0.7152) * cbClamped, false), false) - conversionFormat[1].roundOut((0.33480248 / 0.7152) * crClamped, false), false); 1406e5c31af7Sopenharmony_ci output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.8556 * cbClamped, false), false); 1407e5c31af7Sopenharmony_ci } 1408e5c31af7Sopenharmony_ci else 1409e5c31af7Sopenharmony_ci { 1410e5c31af7Sopenharmony_ci output[0] = conversionFormat[0].roundOut(yClamped + conversionFormat[0].roundOut(1.4746 * crClamped, false), false); 1411e5c31af7Sopenharmony_ci output[1] = conversionFormat[1].roundOut(conversionFormat[1].roundOut(yClamped - conversionFormat[1].roundOut(conversionFormat[1].roundOut(0.11156702 / 0.6780, false) * cbClamped, false), false) - conversionFormat[1].roundOut(conversionFormat[1].roundOut(0.38737742 / 0.6780, false) * crClamped, false), false); 1412e5c31af7Sopenharmony_ci output[2] = conversionFormat[2].roundOut(yClamped + conversionFormat[2].roundOut(1.8814 * cbClamped, false), false); 1413e5c31af7Sopenharmony_ci } 1414e5c31af7Sopenharmony_ci output[3] = input[3]; 1415e5c31af7Sopenharmony_ci break; 1416e5c31af7Sopenharmony_ci } 1417e5c31af7Sopenharmony_ci 1418e5c31af7Sopenharmony_ci default: 1419e5c31af7Sopenharmony_ci DE_FATAL("Unknown YCbCrModel"); 1420e5c31af7Sopenharmony_ci } 1421e5c31af7Sopenharmony_ci 1422e5c31af7Sopenharmony_ci if (colorModel != vk::VK_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY) 1423e5c31af7Sopenharmony_ci { 1424e5c31af7Sopenharmony_ci for (int ndx = 0; ndx < 3; ndx++) 1425e5c31af7Sopenharmony_ci output[ndx] = clampMaybe(output[ndx], 0.0, 1.0); 1426e5c31af7Sopenharmony_ci } 1427e5c31af7Sopenharmony_ci} 1428e5c31af7Sopenharmony_ci 1429e5c31af7Sopenharmony_ciint mirror (int coord) 1430e5c31af7Sopenharmony_ci{ 1431e5c31af7Sopenharmony_ci return coord >= 0 ? coord : -(1 + coord); 1432e5c31af7Sopenharmony_ci} 1433e5c31af7Sopenharmony_ci 1434e5c31af7Sopenharmony_ciint imod (int a, int b) 1435e5c31af7Sopenharmony_ci{ 1436e5c31af7Sopenharmony_ci int m = a % b; 1437e5c31af7Sopenharmony_ci return m < 0 ? m + b : m; 1438e5c31af7Sopenharmony_ci} 1439e5c31af7Sopenharmony_ci 1440e5c31af7Sopenharmony_citcu::Interval frac (const tcu::Interval& x) 1441e5c31af7Sopenharmony_ci{ 1442e5c31af7Sopenharmony_ci if (x.hi() - x.lo() >= 1.0) 1443e5c31af7Sopenharmony_ci return tcu::Interval(0.0, 1.0); 1444e5c31af7Sopenharmony_ci else 1445e5c31af7Sopenharmony_ci { 1446e5c31af7Sopenharmony_ci const tcu::Interval ret (deFrac(x.lo()), deFrac(x.hi())); 1447e5c31af7Sopenharmony_ci 1448e5c31af7Sopenharmony_ci return ret; 1449e5c31af7Sopenharmony_ci } 1450e5c31af7Sopenharmony_ci} 1451e5c31af7Sopenharmony_ci 1452e5c31af7Sopenharmony_citcu::Interval calculateUV (const tcu::FloatFormat& coordFormat, 1453e5c31af7Sopenharmony_ci const tcu::Interval& st, 1454e5c31af7Sopenharmony_ci const int size) 1455e5c31af7Sopenharmony_ci{ 1456e5c31af7Sopenharmony_ci return coordFormat.roundOut(coordFormat.roundOut(st, false) * tcu::Interval((double)size), false); 1457e5c31af7Sopenharmony_ci} 1458e5c31af7Sopenharmony_ci 1459e5c31af7Sopenharmony_citcu::IVec2 calculateNearestIJRange (const tcu::FloatFormat& coordFormat, 1460e5c31af7Sopenharmony_ci const tcu::Interval& uv) 1461e5c31af7Sopenharmony_ci{ 1462e5c31af7Sopenharmony_ci const tcu::Interval ij (coordFormat.roundOut(coordFormat.roundOut(uv, false) - tcu::Interval(0.5), false)); 1463e5c31af7Sopenharmony_ci 1464e5c31af7Sopenharmony_ci return tcu::IVec2(deRoundToInt32(ij.lo() - coordFormat.ulp(ij.lo(), 1)), deRoundToInt32(ij.hi() + coordFormat.ulp(ij.hi(), 1))); 1465e5c31af7Sopenharmony_ci} 1466e5c31af7Sopenharmony_ci 1467e5c31af7Sopenharmony_ci// Calculate range of pixel coordinates that can be used as lower coordinate for linear sampling 1468e5c31af7Sopenharmony_citcu::IVec2 calculateLinearIJRange (const tcu::FloatFormat& coordFormat, 1469e5c31af7Sopenharmony_ci const tcu::Interval& uv) 1470e5c31af7Sopenharmony_ci{ 1471e5c31af7Sopenharmony_ci const tcu::Interval ij (coordFormat.roundOut(uv - tcu::Interval(0.5), false)); 1472e5c31af7Sopenharmony_ci 1473e5c31af7Sopenharmony_ci return tcu::IVec2(deFloorToInt32(ij.lo()), deFloorToInt32(ij.hi())); 1474e5c31af7Sopenharmony_ci} 1475e5c31af7Sopenharmony_ci 1476e5c31af7Sopenharmony_citcu::IVec2 calculateIJRange (vk::VkFilter filter, 1477e5c31af7Sopenharmony_ci const tcu::FloatFormat& coordFormat, 1478e5c31af7Sopenharmony_ci const tcu::Interval& uv) 1479e5c31af7Sopenharmony_ci{ 1480e5c31af7Sopenharmony_ci DE_ASSERT(filter == vk::VK_FILTER_NEAREST || filter == vk::VK_FILTER_LINEAR); 1481e5c31af7Sopenharmony_ci return (filter == vk::VK_FILTER_LINEAR) ? calculateLinearIJRange(coordFormat, uv) 1482e5c31af7Sopenharmony_ci : calculateNearestIJRange(coordFormat, uv); 1483e5c31af7Sopenharmony_ci} 1484e5c31af7Sopenharmony_ci 1485e5c31af7Sopenharmony_citcu::Interval calculateAB (const deUint32 subTexelPrecisionBits, 1486e5c31af7Sopenharmony_ci const tcu::Interval& uv, 1487e5c31af7Sopenharmony_ci int ij) 1488e5c31af7Sopenharmony_ci{ 1489e5c31af7Sopenharmony_ci const deUint32 subdivisions = 0x1u << subTexelPrecisionBits; 1490e5c31af7Sopenharmony_ci const tcu::Interval ab (frac((uv - 0.5) & tcu::Interval((double)ij, (double)(ij + 1)))); 1491e5c31af7Sopenharmony_ci const tcu::Interval gridAB (ab * tcu::Interval(subdivisions)); 1492e5c31af7Sopenharmony_ci const tcu::Interval rounded (de::max(deFloor(gridAB.lo()) / subdivisions, 0.0) , de::min(deCeil(gridAB.hi()) / subdivisions, 1.0)); 1493e5c31af7Sopenharmony_ci 1494e5c31af7Sopenharmony_ci return rounded; 1495e5c31af7Sopenharmony_ci} 1496e5c31af7Sopenharmony_ci 1497e5c31af7Sopenharmony_citcu::Interval lookupWrapped (const ChannelAccess& access, 1498e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1499e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeU, 1500e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeV, 1501e5c31af7Sopenharmony_ci const tcu::IVec2& coord) 1502e5c31af7Sopenharmony_ci{ 1503e5c31af7Sopenharmony_ci return access.getChannel(conversionFormat, 1504e5c31af7Sopenharmony_ci tcu::IVec3(wrap(addressModeU, coord.x(), access.getSize().x()), wrap(addressModeV, coord.y(), access.getSize().y()), 0)); 1505e5c31af7Sopenharmony_ci} 1506e5c31af7Sopenharmony_ci 1507e5c31af7Sopenharmony_citcu::Interval linearInterpolate (const tcu::FloatFormat& filteringFormat, 1508e5c31af7Sopenharmony_ci const tcu::Interval& a, 1509e5c31af7Sopenharmony_ci const tcu::Interval& b, 1510e5c31af7Sopenharmony_ci const tcu::Interval& p00, 1511e5c31af7Sopenharmony_ci const tcu::Interval& p10, 1512e5c31af7Sopenharmony_ci const tcu::Interval& p01, 1513e5c31af7Sopenharmony_ci const tcu::Interval& p11) 1514e5c31af7Sopenharmony_ci{ 1515e5c31af7Sopenharmony_ci const tcu::Interval p[4] = 1516e5c31af7Sopenharmony_ci { 1517e5c31af7Sopenharmony_ci p00, 1518e5c31af7Sopenharmony_ci p10, 1519e5c31af7Sopenharmony_ci p01, 1520e5c31af7Sopenharmony_ci p11 1521e5c31af7Sopenharmony_ci }; 1522e5c31af7Sopenharmony_ci tcu::Interval result (0.0); 1523e5c31af7Sopenharmony_ci 1524e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < 4; ndx++) 1525e5c31af7Sopenharmony_ci { 1526e5c31af7Sopenharmony_ci const tcu::Interval weightA (filteringFormat.roundOut((ndx % 2) == 0 ? (1.0 - a) : a, false)); 1527e5c31af7Sopenharmony_ci const tcu::Interval weightB (filteringFormat.roundOut((ndx / 2) == 0 ? (1.0 - b) : b, false)); 1528e5c31af7Sopenharmony_ci const tcu::Interval weight (filteringFormat.roundOut(weightA * weightB, false)); 1529e5c31af7Sopenharmony_ci 1530e5c31af7Sopenharmony_ci result = filteringFormat.roundOut(result + filteringFormat.roundOut(p[ndx] * weight, false), false); 1531e5c31af7Sopenharmony_ci } 1532e5c31af7Sopenharmony_ci 1533e5c31af7Sopenharmony_ci return result; 1534e5c31af7Sopenharmony_ci} 1535e5c31af7Sopenharmony_ci 1536e5c31af7Sopenharmony_citcu::Interval calculateImplicitChromaUV (const tcu::FloatFormat& coordFormat, 1537e5c31af7Sopenharmony_ci vk::VkChromaLocation offset, 1538e5c31af7Sopenharmony_ci const tcu::Interval& uv) 1539e5c31af7Sopenharmony_ci{ 1540e5c31af7Sopenharmony_ci if (offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN) 1541e5c31af7Sopenharmony_ci return coordFormat.roundOut(0.5 * coordFormat.roundOut(uv + 0.5, false), false); 1542e5c31af7Sopenharmony_ci else 1543e5c31af7Sopenharmony_ci return coordFormat.roundOut(0.5 * uv, false); 1544e5c31af7Sopenharmony_ci} 1545e5c31af7Sopenharmony_ci 1546e5c31af7Sopenharmony_citcu::Interval linearSample (const ChannelAccess& access, 1547e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1548e5c31af7Sopenharmony_ci const tcu::FloatFormat& filteringFormat, 1549e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeU, 1550e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeV, 1551e5c31af7Sopenharmony_ci const tcu::IVec2& coord, 1552e5c31af7Sopenharmony_ci const tcu::Interval& a, 1553e5c31af7Sopenharmony_ci const tcu::Interval& b) 1554e5c31af7Sopenharmony_ci{ 1555e5c31af7Sopenharmony_ci return linearInterpolate(filteringFormat, a, b, 1556e5c31af7Sopenharmony_ci lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(0, 0)), 1557e5c31af7Sopenharmony_ci lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(1, 0)), 1558e5c31af7Sopenharmony_ci lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(0, 1)), 1559e5c31af7Sopenharmony_ci lookupWrapped(access, conversionFormat, addressModeU, addressModeV, coord + tcu::IVec2(1, 1))); 1560e5c31af7Sopenharmony_ci} 1561e5c31af7Sopenharmony_ci 1562e5c31af7Sopenharmony_citcu::Interval reconstructLinearXChromaSample (const tcu::FloatFormat& filteringFormat, 1563e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1564e5c31af7Sopenharmony_ci vk::VkChromaLocation offset, 1565e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeU, 1566e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeV, 1567e5c31af7Sopenharmony_ci const ChannelAccess& access, 1568e5c31af7Sopenharmony_ci int i, 1569e5c31af7Sopenharmony_ci int j) 1570e5c31af7Sopenharmony_ci{ 1571e5c31af7Sopenharmony_ci const int subI = offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1572e5c31af7Sopenharmony_ci ? divFloor(i, 2) 1573e5c31af7Sopenharmony_ci : (i % 2 == 0 ? divFloor(i, 2) - 1 : divFloor(i, 2)); 1574e5c31af7Sopenharmony_ci const double a = offset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1575e5c31af7Sopenharmony_ci ? (i % 2 == 0 ? 0.0 : 0.5) 1576e5c31af7Sopenharmony_ci : (i % 2 == 0 ? 0.25 : 0.75); 1577e5c31af7Sopenharmony_ci 1578e5c31af7Sopenharmony_ci const tcu::Interval A (filteringFormat.roundOut( a * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, tcu::IVec2(subI, j)), false)); 1579e5c31af7Sopenharmony_ci const tcu::Interval B (filteringFormat.roundOut((1.0 - a) * lookupWrapped(access, conversionFormat, addressModeU, addressModeV, tcu::IVec2(subI + 1, j)), false)); 1580e5c31af7Sopenharmony_ci return filteringFormat.roundOut(A + B, false); 1581e5c31af7Sopenharmony_ci} 1582e5c31af7Sopenharmony_ci 1583e5c31af7Sopenharmony_citcu::Interval reconstructLinearXYChromaSample (const tcu::FloatFormat& filteringFormat, 1584e5c31af7Sopenharmony_ci const tcu::FloatFormat& conversionFormat, 1585e5c31af7Sopenharmony_ci vk::VkChromaLocation xOffset, 1586e5c31af7Sopenharmony_ci vk::VkChromaLocation yOffset, 1587e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeU, 1588e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeV, 1589e5c31af7Sopenharmony_ci const ChannelAccess& access, 1590e5c31af7Sopenharmony_ci int i, 1591e5c31af7Sopenharmony_ci int j) 1592e5c31af7Sopenharmony_ci{ 1593e5c31af7Sopenharmony_ci const int subI = xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1594e5c31af7Sopenharmony_ci ? divFloor(i, 2) 1595e5c31af7Sopenharmony_ci : (i % 2 == 0 ? divFloor(i, 2) - 1 : divFloor(i, 2)); 1596e5c31af7Sopenharmony_ci const int subJ = yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1597e5c31af7Sopenharmony_ci ? divFloor(j, 2) 1598e5c31af7Sopenharmony_ci : (j % 2 == 0 ? divFloor(j, 2) - 1 : divFloor(j, 2)); 1599e5c31af7Sopenharmony_ci 1600e5c31af7Sopenharmony_ci const double a = xOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1601e5c31af7Sopenharmony_ci ? (i % 2 == 0 ? 0.0 : 0.5) 1602e5c31af7Sopenharmony_ci : (i % 2 == 0 ? 0.25 : 0.75); 1603e5c31af7Sopenharmony_ci const double b = yOffset == vk::VK_CHROMA_LOCATION_COSITED_EVEN 1604e5c31af7Sopenharmony_ci ? (j % 2 == 0 ? 0.0 : 0.5) 1605e5c31af7Sopenharmony_ci : (j % 2 == 0 ? 0.25 : 0.75); 1606e5c31af7Sopenharmony_ci 1607e5c31af7Sopenharmony_ci return linearSample(access, conversionFormat, filteringFormat, addressModeU, addressModeV, tcu::IVec2(subI, subJ), a, b); 1608e5c31af7Sopenharmony_ci} 1609e5c31af7Sopenharmony_ci 1610e5c31af7Sopenharmony_ciconst ChannelAccess& swizzle (vk::VkComponentSwizzle swizzle, 1611e5c31af7Sopenharmony_ci const ChannelAccess& identityPlane, 1612e5c31af7Sopenharmony_ci const ChannelAccess& rPlane, 1613e5c31af7Sopenharmony_ci const ChannelAccess& gPlane, 1614e5c31af7Sopenharmony_ci const ChannelAccess& bPlane, 1615e5c31af7Sopenharmony_ci const ChannelAccess& aPlane) 1616e5c31af7Sopenharmony_ci{ 1617e5c31af7Sopenharmony_ci switch (swizzle) 1618e5c31af7Sopenharmony_ci { 1619e5c31af7Sopenharmony_ci case vk::VK_COMPONENT_SWIZZLE_IDENTITY: return identityPlane; 1620e5c31af7Sopenharmony_ci case vk::VK_COMPONENT_SWIZZLE_R: return rPlane; 1621e5c31af7Sopenharmony_ci case vk::VK_COMPONENT_SWIZZLE_G: return gPlane; 1622e5c31af7Sopenharmony_ci case vk::VK_COMPONENT_SWIZZLE_B: return bPlane; 1623e5c31af7Sopenharmony_ci case vk::VK_COMPONENT_SWIZZLE_A: return aPlane; 1624e5c31af7Sopenharmony_ci 1625e5c31af7Sopenharmony_ci default: 1626e5c31af7Sopenharmony_ci DE_FATAL("Unsupported swizzle"); 1627e5c31af7Sopenharmony_ci return identityPlane; 1628e5c31af7Sopenharmony_ci } 1629e5c31af7Sopenharmony_ci} 1630e5c31af7Sopenharmony_ci 1631e5c31af7Sopenharmony_ci} // anonymous 1632e5c31af7Sopenharmony_ci 1633e5c31af7Sopenharmony_ciint wrap (vk::VkSamplerAddressMode addressMode, 1634e5c31af7Sopenharmony_ci int coord, 1635e5c31af7Sopenharmony_ci int size) 1636e5c31af7Sopenharmony_ci{ 1637e5c31af7Sopenharmony_ci switch (addressMode) 1638e5c31af7Sopenharmony_ci { 1639e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT: 1640e5c31af7Sopenharmony_ci return (size - 1) - mirror(imod(coord, 2 * size) - size); 1641e5c31af7Sopenharmony_ci 1642e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_ADDRESS_MODE_REPEAT: 1643e5c31af7Sopenharmony_ci return imod(coord, size); 1644e5c31af7Sopenharmony_ci 1645e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE: 1646e5c31af7Sopenharmony_ci return de::clamp(coord, 0, size - 1); 1647e5c31af7Sopenharmony_ci 1648e5c31af7Sopenharmony_ci case vk::VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE: 1649e5c31af7Sopenharmony_ci return de::clamp(mirror(coord), 0, size - 1); 1650e5c31af7Sopenharmony_ci 1651e5c31af7Sopenharmony_ci default: 1652e5c31af7Sopenharmony_ci DE_FATAL("Unknown wrap mode"); 1653e5c31af7Sopenharmony_ci return ~0; 1654e5c31af7Sopenharmony_ci } 1655e5c31af7Sopenharmony_ci} 1656e5c31af7Sopenharmony_ci 1657e5c31af7Sopenharmony_ciint divFloor (int a, int b) 1658e5c31af7Sopenharmony_ci{ 1659e5c31af7Sopenharmony_ci if (a % b == 0) 1660e5c31af7Sopenharmony_ci return a / b; 1661e5c31af7Sopenharmony_ci else if (a > 0) 1662e5c31af7Sopenharmony_ci return a / b; 1663e5c31af7Sopenharmony_ci else 1664e5c31af7Sopenharmony_ci return (a / b) - 1; 1665e5c31af7Sopenharmony_ci} 1666e5c31af7Sopenharmony_ci 1667e5c31af7Sopenharmony_civoid calculateBounds (const ChannelAccess& rPlane, 1668e5c31af7Sopenharmony_ci const ChannelAccess& gPlane, 1669e5c31af7Sopenharmony_ci const ChannelAccess& bPlane, 1670e5c31af7Sopenharmony_ci const ChannelAccess& aPlane, 1671e5c31af7Sopenharmony_ci const UVec4& bitDepth, 1672e5c31af7Sopenharmony_ci const vector<Vec2>& sts, 1673e5c31af7Sopenharmony_ci const vector<FloatFormat>& filteringFormat, 1674e5c31af7Sopenharmony_ci const vector<FloatFormat>& conversionFormat, 1675e5c31af7Sopenharmony_ci const deUint32 subTexelPrecisionBits, 1676e5c31af7Sopenharmony_ci vk::VkFilter filter, 1677e5c31af7Sopenharmony_ci vk::VkSamplerYcbcrModelConversion colorModel, 1678e5c31af7Sopenharmony_ci vk::VkSamplerYcbcrRange range, 1679e5c31af7Sopenharmony_ci vk::VkFilter chromaFilter, 1680e5c31af7Sopenharmony_ci vk::VkChromaLocation xChromaOffset, 1681e5c31af7Sopenharmony_ci vk::VkChromaLocation yChromaOffset, 1682e5c31af7Sopenharmony_ci const vk::VkComponentMapping& componentMapping, 1683e5c31af7Sopenharmony_ci bool explicitReconstruction, 1684e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeU, 1685e5c31af7Sopenharmony_ci vk::VkSamplerAddressMode addressModeV, 1686e5c31af7Sopenharmony_ci std::vector<Vec4>& minBounds, 1687e5c31af7Sopenharmony_ci std::vector<Vec4>& maxBounds, 1688e5c31af7Sopenharmony_ci std::vector<Vec4>& uvBounds, 1689e5c31af7Sopenharmony_ci std::vector<IVec4>& ijBounds) 1690e5c31af7Sopenharmony_ci{ 1691e5c31af7Sopenharmony_ci const FloatFormat highp (-126, 127, 23, true, 1692e5c31af7Sopenharmony_ci tcu::MAYBE, // subnormals 1693e5c31af7Sopenharmony_ci tcu::YES, // infinities 1694e5c31af7Sopenharmony_ci tcu::MAYBE); // NaN 1695e5c31af7Sopenharmony_ci const FloatFormat coordFormat (-32, 32, 16, true); 1696e5c31af7Sopenharmony_ci const ChannelAccess& rAccess (swizzle(componentMapping.r, rPlane, rPlane, gPlane, bPlane, aPlane)); 1697e5c31af7Sopenharmony_ci const ChannelAccess& gAccess (swizzle(componentMapping.g, gPlane, rPlane, gPlane, bPlane, aPlane)); 1698e5c31af7Sopenharmony_ci const ChannelAccess& bAccess (swizzle(componentMapping.b, bPlane, rPlane, gPlane, bPlane, aPlane)); 1699e5c31af7Sopenharmony_ci const ChannelAccess& aAccess (swizzle(componentMapping.a, aPlane, rPlane, gPlane, bPlane, aPlane)); 1700e5c31af7Sopenharmony_ci 1701e5c31af7Sopenharmony_ci const bool subsampledX = gAccess.getSize().x() > rAccess.getSize().x(); 1702e5c31af7Sopenharmony_ci const bool subsampledY = gAccess.getSize().y() > rAccess.getSize().y(); 1703e5c31af7Sopenharmony_ci 1704e5c31af7Sopenharmony_ci minBounds.resize(sts.size(), Vec4(TCU_INFINITY)); 1705e5c31af7Sopenharmony_ci maxBounds.resize(sts.size(), Vec4(-TCU_INFINITY)); 1706e5c31af7Sopenharmony_ci 1707e5c31af7Sopenharmony_ci uvBounds.resize(sts.size(), Vec4(TCU_INFINITY, -TCU_INFINITY, TCU_INFINITY, -TCU_INFINITY)); 1708e5c31af7Sopenharmony_ci ijBounds.resize(sts.size(), IVec4(0x7FFFFFFF, -1 -0x7FFFFFFF, 0x7FFFFFFF, -1 -0x7FFFFFFF)); 1709e5c31af7Sopenharmony_ci 1710e5c31af7Sopenharmony_ci // Chroma plane sizes must match 1711e5c31af7Sopenharmony_ci DE_ASSERT(rAccess.getSize() == bAccess.getSize()); 1712e5c31af7Sopenharmony_ci 1713e5c31af7Sopenharmony_ci // Luma plane sizes must match 1714e5c31af7Sopenharmony_ci DE_ASSERT(gAccess.getSize() == aAccess.getSize()); 1715e5c31af7Sopenharmony_ci 1716e5c31af7Sopenharmony_ci // Luma plane size must match chroma plane or be twice as big 1717e5c31af7Sopenharmony_ci DE_ASSERT(rAccess.getSize().x() == gAccess.getSize().x() || 2 * rAccess.getSize().x() == gAccess.getSize().x()); 1718e5c31af7Sopenharmony_ci DE_ASSERT(rAccess.getSize().y() == gAccess.getSize().y() || 2 * rAccess.getSize().y() == gAccess.getSize().y()); 1719e5c31af7Sopenharmony_ci 1720e5c31af7Sopenharmony_ci DE_ASSERT(filter == vk::VK_FILTER_NEAREST || filter == vk::VK_FILTER_LINEAR); 1721e5c31af7Sopenharmony_ci DE_ASSERT(chromaFilter == vk::VK_FILTER_NEAREST || chromaFilter == vk::VK_FILTER_LINEAR); 1722e5c31af7Sopenharmony_ci DE_ASSERT(subsampledX || !subsampledY); 1723e5c31af7Sopenharmony_ci 1724e5c31af7Sopenharmony_ci 1725e5c31af7Sopenharmony_ci for (size_t ndx = 0; ndx < sts.size(); ndx++) 1726e5c31af7Sopenharmony_ci { 1727e5c31af7Sopenharmony_ci const Vec2 st (sts[ndx]); 1728e5c31af7Sopenharmony_ci Interval bounds[4]; 1729e5c31af7Sopenharmony_ci 1730e5c31af7Sopenharmony_ci const Interval u (calculateUV(coordFormat, st[0], gAccess.getSize().x())); 1731e5c31af7Sopenharmony_ci const Interval v (calculateUV(coordFormat, st[1], gAccess.getSize().y())); 1732e5c31af7Sopenharmony_ci 1733e5c31af7Sopenharmony_ci uvBounds[ndx][0] = (float)u.lo(); 1734e5c31af7Sopenharmony_ci uvBounds[ndx][1] = (float)u.hi(); 1735e5c31af7Sopenharmony_ci 1736e5c31af7Sopenharmony_ci uvBounds[ndx][2] = (float)v.lo(); 1737e5c31af7Sopenharmony_ci uvBounds[ndx][3] = (float)v.hi(); 1738e5c31af7Sopenharmony_ci 1739e5c31af7Sopenharmony_ci const IVec2 iRange (calculateIJRange(filter, coordFormat, u)); 1740e5c31af7Sopenharmony_ci const IVec2 jRange (calculateIJRange(filter, coordFormat, v)); 1741e5c31af7Sopenharmony_ci 1742e5c31af7Sopenharmony_ci ijBounds[ndx][0] = iRange[0]; 1743e5c31af7Sopenharmony_ci ijBounds[ndx][1] = iRange[1]; 1744e5c31af7Sopenharmony_ci 1745e5c31af7Sopenharmony_ci ijBounds[ndx][2] = jRange[0]; 1746e5c31af7Sopenharmony_ci ijBounds[ndx][3] = jRange[1]; 1747e5c31af7Sopenharmony_ci 1748e5c31af7Sopenharmony_ci for (int j = jRange.x(); j <= jRange.y(); j++) 1749e5c31af7Sopenharmony_ci for (int i = iRange.x(); i <= iRange.y(); i++) 1750e5c31af7Sopenharmony_ci { 1751e5c31af7Sopenharmony_ci if (filter == vk::VK_FILTER_NEAREST) 1752e5c31af7Sopenharmony_ci { 1753e5c31af7Sopenharmony_ci const Interval gValue (lookupWrapped(gAccess, conversionFormat[1], addressModeU, addressModeV, IVec2(i, j))); 1754e5c31af7Sopenharmony_ci const Interval aValue (lookupWrapped(aAccess, conversionFormat[3], addressModeU, addressModeV, IVec2(i, j))); 1755e5c31af7Sopenharmony_ci 1756e5c31af7Sopenharmony_ci if (explicitReconstruction || !(subsampledX || subsampledY)) 1757e5c31af7Sopenharmony_ci { 1758e5c31af7Sopenharmony_ci Interval rValue, bValue; 1759e5c31af7Sopenharmony_ci if (chromaFilter == vk::VK_FILTER_NEAREST || !subsampledX) 1760e5c31af7Sopenharmony_ci { 1761e5c31af7Sopenharmony_ci // Reconstruct using nearest if needed, otherwise, just take what's already there. 1762e5c31af7Sopenharmony_ci const int subI = subsampledX ? i / 2 : i; 1763e5c31af7Sopenharmony_ci const int subJ = subsampledY ? j / 2 : j; 1764e5c31af7Sopenharmony_ci rValue = lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(subI, subJ)); 1765e5c31af7Sopenharmony_ci bValue = lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(subI, subJ)); 1766e5c31af7Sopenharmony_ci } 1767e5c31af7Sopenharmony_ci else // vk::VK_FILTER_LINEAR 1768e5c31af7Sopenharmony_ci { 1769e5c31af7Sopenharmony_ci if (subsampledY) 1770e5c31af7Sopenharmony_ci { 1771e5c31af7Sopenharmony_ci rValue = reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j); 1772e5c31af7Sopenharmony_ci bValue = reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j); 1773e5c31af7Sopenharmony_ci } 1774e5c31af7Sopenharmony_ci else 1775e5c31af7Sopenharmony_ci { 1776e5c31af7Sopenharmony_ci rValue = reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i, j); 1777e5c31af7Sopenharmony_ci bValue = reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i, j); 1778e5c31af7Sopenharmony_ci } 1779e5c31af7Sopenharmony_ci } 1780e5c31af7Sopenharmony_ci 1781e5c31af7Sopenharmony_ci const Interval srcColor[] = 1782e5c31af7Sopenharmony_ci { 1783e5c31af7Sopenharmony_ci rValue, 1784e5c31af7Sopenharmony_ci gValue, 1785e5c31af7Sopenharmony_ci bValue, 1786e5c31af7Sopenharmony_ci aValue 1787e5c31af7Sopenharmony_ci }; 1788e5c31af7Sopenharmony_ci Interval dstColor[4]; 1789e5c31af7Sopenharmony_ci 1790e5c31af7Sopenharmony_ci convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor); 1791e5c31af7Sopenharmony_ci 1792e5c31af7Sopenharmony_ci for (size_t compNdx = 0; compNdx < 4; compNdx++) 1793e5c31af7Sopenharmony_ci bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false); 1794e5c31af7Sopenharmony_ci } 1795e5c31af7Sopenharmony_ci else 1796e5c31af7Sopenharmony_ci { 1797e5c31af7Sopenharmony_ci const Interval chromaU (subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u); 1798e5c31af7Sopenharmony_ci const Interval chromaV (subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v); 1799e5c31af7Sopenharmony_ci 1800e5c31af7Sopenharmony_ci // Reconstructed chroma samples with implicit filtering 1801e5c31af7Sopenharmony_ci const IVec2 chromaIRange (subsampledX ? calculateIJRange(chromaFilter, coordFormat, chromaU) : IVec2(i, i)); 1802e5c31af7Sopenharmony_ci const IVec2 chromaJRange (subsampledY ? calculateIJRange(chromaFilter, coordFormat, chromaV) : IVec2(j, j)); 1803e5c31af7Sopenharmony_ci 1804e5c31af7Sopenharmony_ci for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++) 1805e5c31af7Sopenharmony_ci for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.y(); chromaI++) 1806e5c31af7Sopenharmony_ci { 1807e5c31af7Sopenharmony_ci Interval rValue, bValue; 1808e5c31af7Sopenharmony_ci 1809e5c31af7Sopenharmony_ci if (chromaFilter == vk::VK_FILTER_NEAREST) 1810e5c31af7Sopenharmony_ci { 1811e5c31af7Sopenharmony_ci rValue = lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ)); 1812e5c31af7Sopenharmony_ci bValue = lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ)); 1813e5c31af7Sopenharmony_ci } 1814e5c31af7Sopenharmony_ci else // vk::VK_FILTER_LINEAR 1815e5c31af7Sopenharmony_ci { 1816e5c31af7Sopenharmony_ci const Interval chromaA (calculateAB(subTexelPrecisionBits, chromaU, chromaI)); 1817e5c31af7Sopenharmony_ci const Interval chromaB (calculateAB(subTexelPrecisionBits, chromaV, chromaJ)); 1818e5c31af7Sopenharmony_ci 1819e5c31af7Sopenharmony_ci rValue = linearSample(rAccess, conversionFormat[0], filteringFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB); 1820e5c31af7Sopenharmony_ci bValue = linearSample(bAccess, conversionFormat[2], filteringFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB); 1821e5c31af7Sopenharmony_ci } 1822e5c31af7Sopenharmony_ci 1823e5c31af7Sopenharmony_ci const Interval srcColor[] = 1824e5c31af7Sopenharmony_ci { 1825e5c31af7Sopenharmony_ci rValue, 1826e5c31af7Sopenharmony_ci gValue, 1827e5c31af7Sopenharmony_ci bValue, 1828e5c31af7Sopenharmony_ci aValue 1829e5c31af7Sopenharmony_ci }; 1830e5c31af7Sopenharmony_ci 1831e5c31af7Sopenharmony_ci Interval dstColor[4]; 1832e5c31af7Sopenharmony_ci convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor); 1833e5c31af7Sopenharmony_ci 1834e5c31af7Sopenharmony_ci for (size_t compNdx = 0; compNdx < 4; compNdx++) 1835e5c31af7Sopenharmony_ci bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false); 1836e5c31af7Sopenharmony_ci } 1837e5c31af7Sopenharmony_ci } 1838e5c31af7Sopenharmony_ci } 1839e5c31af7Sopenharmony_ci else // filter == vk::VK_FILTER_LINEAR 1840e5c31af7Sopenharmony_ci { 1841e5c31af7Sopenharmony_ci const Interval lumaA (calculateAB(subTexelPrecisionBits, u, i)); 1842e5c31af7Sopenharmony_ci const Interval lumaB (calculateAB(subTexelPrecisionBits, v, j)); 1843e5c31af7Sopenharmony_ci 1844e5c31af7Sopenharmony_ci const Interval gValue (linearSample(gAccess, conversionFormat[1], filteringFormat[1], addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB)); 1845e5c31af7Sopenharmony_ci const Interval aValue (linearSample(aAccess, conversionFormat[3], filteringFormat[3], addressModeU, addressModeV, IVec2(i, j), lumaA, lumaB)); 1846e5c31af7Sopenharmony_ci 1847e5c31af7Sopenharmony_ci if (explicitReconstruction || !(subsampledX || subsampledY)) 1848e5c31af7Sopenharmony_ci { 1849e5c31af7Sopenharmony_ci Interval rValue, bValue; 1850e5c31af7Sopenharmony_ci if (chromaFilter == vk::VK_FILTER_NEAREST || !subsampledX) 1851e5c31af7Sopenharmony_ci { 1852e5c31af7Sopenharmony_ci rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB, 1853e5c31af7Sopenharmony_ci lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))), 1854e5c31af7Sopenharmony_ci lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))), 1855e5c31af7Sopenharmony_ci lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))), 1856e5c31af7Sopenharmony_ci lookupWrapped(rAccess, conversionFormat[0], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1)))); 1857e5c31af7Sopenharmony_ci bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB, 1858e5c31af7Sopenharmony_ci lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))), 1859e5c31af7Sopenharmony_ci lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), j / (subsampledY ? 2 : 1))), 1860e5c31af7Sopenharmony_ci lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2(i / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1))), 1861e5c31af7Sopenharmony_ci lookupWrapped(bAccess, conversionFormat[2], addressModeU, addressModeV, IVec2((i + 1) / (subsampledX ? 2 : 1), (j + 1) / (subsampledY ? 2 : 1)))); 1862e5c31af7Sopenharmony_ci } 1863e5c31af7Sopenharmony_ci else // vk::VK_FILTER_LINEAR 1864e5c31af7Sopenharmony_ci { 1865e5c31af7Sopenharmony_ci if (subsampledY) 1866e5c31af7Sopenharmony_ci { 1867e5c31af7Sopenharmony_ci // Linear, Reconstructed xx chroma samples with explicit linear filtering 1868e5c31af7Sopenharmony_ci rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB, 1869e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i, j), 1870e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j), 1871e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1), 1872e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, yChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1)); 1873e5c31af7Sopenharmony_ci bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB, 1874e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i, j), 1875e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j), 1876e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1), 1877e5c31af7Sopenharmony_ci reconstructLinearXYChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, yChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1)); 1878e5c31af7Sopenharmony_ci } 1879e5c31af7Sopenharmony_ci else 1880e5c31af7Sopenharmony_ci { 1881e5c31af7Sopenharmony_ci // Linear, Reconstructed x chroma samples with explicit linear filtering 1882e5c31af7Sopenharmony_ci rValue = linearInterpolate(filteringFormat[0], lumaA, lumaB, 1883e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i, j), 1884e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j), 1885e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i , j + 1), 1886e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[0], conversionFormat[0], xChromaOffset, addressModeU, addressModeV, rAccess, i + 1, j + 1)); 1887e5c31af7Sopenharmony_ci bValue = linearInterpolate(filteringFormat[2], lumaA, lumaB, 1888e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i, j), 1889e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j), 1890e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i , j + 1), 1891e5c31af7Sopenharmony_ci reconstructLinearXChromaSample(filteringFormat[2], conversionFormat[2], xChromaOffset, addressModeU, addressModeV, bAccess, i + 1, j + 1)); 1892e5c31af7Sopenharmony_ci } 1893e5c31af7Sopenharmony_ci } 1894e5c31af7Sopenharmony_ci 1895e5c31af7Sopenharmony_ci const Interval srcColor[] = 1896e5c31af7Sopenharmony_ci { 1897e5c31af7Sopenharmony_ci rValue, 1898e5c31af7Sopenharmony_ci gValue, 1899e5c31af7Sopenharmony_ci bValue, 1900e5c31af7Sopenharmony_ci aValue 1901e5c31af7Sopenharmony_ci }; 1902e5c31af7Sopenharmony_ci Interval dstColor[4]; 1903e5c31af7Sopenharmony_ci 1904e5c31af7Sopenharmony_ci convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor); 1905e5c31af7Sopenharmony_ci 1906e5c31af7Sopenharmony_ci for (size_t compNdx = 0; compNdx < 4; compNdx++) 1907e5c31af7Sopenharmony_ci bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false); 1908e5c31af7Sopenharmony_ci } 1909e5c31af7Sopenharmony_ci else 1910e5c31af7Sopenharmony_ci { 1911e5c31af7Sopenharmony_ci const Interval chromaU (subsampledX ? calculateImplicitChromaUV(coordFormat, xChromaOffset, u) : u); 1912e5c31af7Sopenharmony_ci const Interval chromaV (subsampledY ? calculateImplicitChromaUV(coordFormat, yChromaOffset, v) : v); 1913e5c31af7Sopenharmony_ci 1914e5c31af7Sopenharmony_ci // TODO: It looks incorrect to ignore the chroma filter here. Is it? 1915e5c31af7Sopenharmony_ci const IVec2 chromaIRange (calculateNearestIJRange(coordFormat, chromaU)); 1916e5c31af7Sopenharmony_ci const IVec2 chromaJRange (calculateNearestIJRange(coordFormat, chromaV)); 1917e5c31af7Sopenharmony_ci 1918e5c31af7Sopenharmony_ci for (int chromaJ = chromaJRange.x(); chromaJ <= chromaJRange.y(); chromaJ++) 1919e5c31af7Sopenharmony_ci for (int chromaI = chromaIRange.x(); chromaI <= chromaIRange.y(); chromaI++) 1920e5c31af7Sopenharmony_ci { 1921e5c31af7Sopenharmony_ci Interval rValue, bValue; 1922e5c31af7Sopenharmony_ci 1923e5c31af7Sopenharmony_ci if (chromaFilter == vk::VK_FILTER_NEAREST) 1924e5c31af7Sopenharmony_ci { 1925e5c31af7Sopenharmony_ci rValue = lookupWrapped(rAccess, conversionFormat[1], addressModeU, addressModeV, IVec2(chromaI, chromaJ)); 1926e5c31af7Sopenharmony_ci bValue = lookupWrapped(bAccess, conversionFormat[3], addressModeU, addressModeV, IVec2(chromaI, chromaJ)); 1927e5c31af7Sopenharmony_ci } 1928e5c31af7Sopenharmony_ci else // vk::VK_FILTER_LINEAR 1929e5c31af7Sopenharmony_ci { 1930e5c31af7Sopenharmony_ci const Interval chromaA (calculateAB(subTexelPrecisionBits, chromaU, chromaI)); 1931e5c31af7Sopenharmony_ci const Interval chromaB (calculateAB(subTexelPrecisionBits, chromaV, chromaJ)); 1932e5c31af7Sopenharmony_ci 1933e5c31af7Sopenharmony_ci rValue = linearSample(rAccess, conversionFormat[0], filteringFormat[0], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB); 1934e5c31af7Sopenharmony_ci bValue = linearSample(bAccess, conversionFormat[2], filteringFormat[2], addressModeU, addressModeV, IVec2(chromaI, chromaJ), chromaA, chromaB); 1935e5c31af7Sopenharmony_ci } 1936e5c31af7Sopenharmony_ci 1937e5c31af7Sopenharmony_ci const Interval srcColor[] = 1938e5c31af7Sopenharmony_ci { 1939e5c31af7Sopenharmony_ci rValue, 1940e5c31af7Sopenharmony_ci gValue, 1941e5c31af7Sopenharmony_ci bValue, 1942e5c31af7Sopenharmony_ci aValue 1943e5c31af7Sopenharmony_ci }; 1944e5c31af7Sopenharmony_ci Interval dstColor[4]; 1945e5c31af7Sopenharmony_ci convertColor(colorModel, range, conversionFormat, bitDepth, srcColor, dstColor); 1946e5c31af7Sopenharmony_ci 1947e5c31af7Sopenharmony_ci for (size_t compNdx = 0; compNdx < 4; compNdx++) 1948e5c31af7Sopenharmony_ci bounds[compNdx] |= highp.roundOut(dstColor[compNdx], false); 1949e5c31af7Sopenharmony_ci } 1950e5c31af7Sopenharmony_ci } 1951e5c31af7Sopenharmony_ci } 1952e5c31af7Sopenharmony_ci } 1953e5c31af7Sopenharmony_ci 1954e5c31af7Sopenharmony_ci minBounds[ndx] = Vec4((float)bounds[0].lo(), (float)bounds[1].lo(), (float)bounds[2].lo(), (float)bounds[3].lo()); 1955e5c31af7Sopenharmony_ci maxBounds[ndx] = Vec4((float)bounds[0].hi(), (float)bounds[1].hi(), (float)bounds[2].hi(), (float)bounds[3].hi()); 1956e5c31af7Sopenharmony_ci } 1957e5c31af7Sopenharmony_ci} 1958e5c31af7Sopenharmony_ci 1959e5c31af7Sopenharmony_ci} // ycbcr 1960e5c31af7Sopenharmony_ci 1961e5c31af7Sopenharmony_ci} // vkt 1962