1 #ifndef _VKTYCBCRUTIL_HPP 2 #define _VKTYCBCRUTIL_HPP 3 /*------------------------------------------------------------------------- 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2017 Google Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief YCbCr Test Utilities 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 28 #include "vktTestCase.hpp" 29 30 #include "vkImageUtil.hpp" 31 #include "vkMemUtil.hpp" 32 #include "vkRef.hpp" 33 34 #include "deSharedPtr.hpp" 35 #include "deRandom.hpp" 36 37 #include "tcuTextureUtil.hpp" 38 #include "tcuFloatFormat.hpp" 39 #include "tcuFloat.hpp" 40 #include "tcuInterval.hpp" 41 #include "tcuFloatFormat.hpp" 42 #include "tcuFloat.hpp" 43 44 #include <vector> 45 46 namespace vkt 47 { 48 namespace ycbcr 49 { 50 51 #define VK_YCBCR_FORMAT_FIRST VK_FORMAT_G8B8G8R8_422_UNORM 52 #define VK_YCBCR_FORMAT_LAST ((vk::VkFormat)(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM + 1)) 53 54 typedef de::SharedPtr<vk::Allocation> AllocationSp; 55 typedef de::SharedPtr<vk::Unique<vk::VkBuffer>> VkBufferSp; 56 57 class MultiPlaneImageData 58 { 59 public: 60 MultiPlaneImageData(vk::VkFormat format, const tcu::UVec2 &size); 61 MultiPlaneImageData(const MultiPlaneImageData &); 62 ~MultiPlaneImageData(void); 63 getFormat(void) const64 vk::VkFormat getFormat(void) const 65 { 66 return m_format; 67 } getDescription(void) const68 const vk::PlanarFormatDescription &getDescription(void) const 69 { 70 return m_description; 71 } getSize(void) const72 const tcu::UVec2 &getSize(void) const 73 { 74 return m_size; 75 } 76 getPlaneSize(uint32_t planeNdx) const77 size_t getPlaneSize(uint32_t planeNdx) const 78 { 79 return m_planeData[planeNdx].size(); 80 } getPlanePtr(uint32_t planeNdx)81 void *getPlanePtr(uint32_t planeNdx) 82 { 83 return &m_planeData[planeNdx][0]; 84 } getPlanePtr(uint32_t planeNdx) const85 const void *getPlanePtr(uint32_t planeNdx) const 86 { 87 return &m_planeData[planeNdx][0]; 88 } 89 90 tcu::PixelBufferAccess getChannelAccess(uint32_t channelNdx); 91 tcu::ConstPixelBufferAccess getChannelAccess(uint32_t channelNdx) const; 92 93 private: 94 MultiPlaneImageData &operator=(const MultiPlaneImageData &); 95 96 const vk::VkFormat m_format; 97 const vk::PlanarFormatDescription m_description; 98 const tcu::UVec2 m_size; 99 100 std::vector<uint8_t> m_planeData[vk::PlanarFormatDescription::MAX_PLANES]; 101 }; 102 103 void checkImageSupport(Context &context, vk::VkFormat format, vk::VkImageCreateFlags createFlags, 104 vk::VkImageTiling tiling = vk::VK_IMAGE_TILING_OPTIMAL); 105 106 void fillRandomNoNaN(de::Random *randomGen, uint8_t *const data, uint32_t size, const vk::VkFormat format); 107 void fillRandom(de::Random *randomGen, MultiPlaneImageData *imageData, 108 const vk::VkFormat format = vk::VK_FORMAT_UNDEFINED, bool noNan = false); 109 void fillGradient(MultiPlaneImageData *imageData, const tcu::Vec4 &minVal, const tcu::Vec4 &maxVal); 110 void fillZero(MultiPlaneImageData *imageData); 111 112 std::vector<de::SharedPtr<vk::Allocation>> allocateAndBindImageMemory( 113 const vk::DeviceInterface &vkd, vk::VkDevice device, vk::Allocator &allocator, vk::VkImage image, 114 vk::VkFormat format, vk::VkImageCreateFlags createFlags, 115 vk::MemoryRequirement requirement = vk::MemoryRequirement::Any); 116 117 void uploadImage(const vk::DeviceInterface &vkd, vk::VkDevice device, uint32_t queueFamilyNdx, vk::Allocator &allocator, 118 vk::VkImage image, const MultiPlaneImageData &imageData, vk::VkAccessFlags nextAccess, 119 vk::VkImageLayout finalLayout, uint32_t arrayLayer = 0u); 120 121 void fillImageMemory(const vk::DeviceInterface &vkd, vk::VkDevice device, uint32_t queueFamilyNdx, vk::VkImage image, 122 const std::vector<de::SharedPtr<vk::Allocation>> &memory, const MultiPlaneImageData &imageData, 123 vk::VkAccessFlags nextAccess, vk::VkImageLayout finalLayout, uint32_t arrayLayer = 0u); 124 125 void downloadImage(const vk::DeviceInterface &vkd, vk::VkDevice device, uint32_t queueFamilyNdx, 126 vk::Allocator &allocator, vk::VkImage image, MultiPlaneImageData *imageData, 127 vk::VkAccessFlags prevAccess, vk::VkImageLayout initialLayout, uint32_t baseArrayLayer = 0); 128 129 void readImageMemory(const vk::DeviceInterface &vkd, vk::VkDevice device, uint32_t queueFamilyNdx, vk::VkImage image, 130 const std::vector<de::SharedPtr<vk::Allocation>> &memory, MultiPlaneImageData *imageData, 131 vk::VkAccessFlags prevAccess, vk::VkImageLayout initialLayout); 132 133 class ChannelAccess 134 { 135 public: 136 ChannelAccess(tcu::TextureChannelClass channelClass, uint8_t channelSize, const tcu::IVec3 &size, 137 const tcu::IVec3 &bitPitch, void *data, uint32_t bitOffset); 138 getSize(void) const139 const tcu::IVec3 &getSize(void) const 140 { 141 return m_size; 142 } getBitPitch(void) const143 const tcu::IVec3 &getBitPitch(void) const 144 { 145 return m_bitPitch; 146 } getDataPtr(void) const147 void *getDataPtr(void) const 148 { 149 return m_data; 150 } 151 152 tcu::Interval getChannel(const tcu::FloatFormat &conversionFormat, const tcu::IVec3 &pos) const; 153 uint32_t getChannelUint(const tcu::IVec3 &pos) const; 154 float getChannel(const tcu::IVec3 &pos) const; 155 void setChannel(const tcu::IVec3 &pos, uint32_t x); 156 void setChannel(const tcu::IVec3 &pos, float x); 157 158 private: 159 const tcu::TextureChannelClass m_channelClass; 160 const uint8_t m_channelSize; 161 const tcu::IVec3 m_size; 162 const tcu::IVec3 m_bitPitch; 163 void *const m_data; 164 const int32_t m_bitOffset; 165 }; 166 167 ChannelAccess getChannelAccess(ycbcr::MultiPlaneImageData &data, const vk::PlanarFormatDescription &formatInfo, 168 const tcu::UVec2 &size, int channelNdx); 169 170 bool isYChromaSubsampled(vk::VkFormat format); 171 172 bool isXChromaSubsampled(vk::VkFormat format); 173 174 bool areLsb6BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat); 175 176 bool areLsb4BitsDontCare(vk::VkFormat srcFormat, vk::VkFormat dstFormat); 177 178 tcu::UVec4 getYCbCrBitDepth(vk::VkFormat format); 179 180 std::vector<tcu::FloatFormat> getPrecision(vk::VkFormat format); 181 182 uint32_t getYCbCrFormatChannelCount(vk::VkFormat format); 183 184 int wrap(vk::VkSamplerAddressMode addressMode, int coord, int size); 185 186 int divFloor(int a, int b); 187 188 void calculateBounds(const ChannelAccess &rPlane, const ChannelAccess &gPlane, const ChannelAccess &bPlane, 189 const ChannelAccess &aPlane, const tcu::UVec4 &bitDepth, const std::vector<tcu::Vec2> &sts, 190 const std::vector<tcu::FloatFormat> &filteringFormat, 191 const std::vector<tcu::FloatFormat> &conversionFormat, const uint32_t subTexelPrecisionBits, 192 vk::VkFilter filter, vk::VkSamplerYcbcrModelConversion colorModel, vk::VkSamplerYcbcrRange range, 193 vk::VkFilter chromaFilter, vk::VkChromaLocation xChromaOffset, vk::VkChromaLocation yChromaOffset, 194 const vk::VkComponentMapping &componentMapping, bool explicitReconstruction, 195 vk::VkSamplerAddressMode addressModeU, vk::VkSamplerAddressMode addressModeV, 196 std::vector<tcu::Vec4> &minBounds, std::vector<tcu::Vec4> &maxBounds, 197 std::vector<tcu::Vec4> &uvBounds, std::vector<tcu::IVec4> &ijBounds); 198 199 } // namespace ycbcr 200 } // namespace vkt 201 202 #endif // _VKTYCBCRUTIL_HPP 203