1 #ifndef _VKTEXTERNALMEMORYANDROIDHARDWAREBUFFERUTIL_HPP 2 #define _VKTEXTERNALMEMORYANDROIDHARDWAREBUFFERUTIL_HPP 3 /*------------------------------------------------------------------------- 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2023 The Khronos Group Inc. 8 * Copyright (c) 2023 Google Inc. 9 * Copyright (c) 2023 LunarG Inc. 10 * 11 * Licensed under the Apache License, Version 2.0 (the "License"); 12 * you may not use this file except in compliance with the License. 13 * You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 * 23 *//*! 24 * \file 25 * \brief Vulkan external memory utilities for Android Hardware Buffer 26 *//*--------------------------------------------------------------------*/ 27 28 #include "tcuDefs.hpp" 29 30 #include "vkPlatform.hpp" 31 #include "vkRefUtil.hpp" 32 33 #include "tcuTexture.hpp" 34 #include "tcuCompressedTexture.hpp" 35 36 #include <vector> 37 38 #ifndef CTS_USES_VULKANSC 39 40 namespace vkt 41 { 42 43 namespace ExternalMemoryUtil 44 { 45 46 class AndroidHardwareBufferExternalApi 47 { 48 public: 49 /** 50 * getInstance obtains the object, that provides an interface to AHB system APIs . 51 * If the AHB system API is not supported or if it is not built as supported with the CTS, 52 * then this function would return a null object. 53 */ 54 static AndroidHardwareBufferExternalApi *getInstance(); 55 56 /* Is AndroidHardwareBuffer supported? */ 57 static bool supportsAhb(); 58 59 /* Are Cube maps supported on current api level? */ 60 static bool supportsCubeMap(); 61 62 /** 63 * Allocates a buffer that backs an AHardwareBuffer using the passed parameter as follows: 64 * width; - width in pixels 65 * height; - height in pixels 66 * layers; - number of images 67 * format; - One of AHARDWAREBUFFER_FORMAT_* 68 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 69 * 70 * Returns a valid AndroidHardwareBufferPtr object on success, or an null AndroidHardwareBufferPtr if 71 * the allocation fails for any reason. 72 */ 73 virtual vk::pt::AndroidHardwareBufferPtr allocate(uint32_t width, uint32_t height, uint32_t layers, uint32_t format, 74 uint64_t usage) = 0; 75 76 /** 77 * Acquire a reference on the given AHardwareBuffer object. This prevents the 78 * object from being deleted until the last reference is removed. 79 */ 80 virtual void acquire(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 81 82 /** 83 * Remove a reference that was previously acquired with 84 * AHardwareBuffer_acquire(). 85 */ 86 virtual void release(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 87 88 /** 89 * Return a description of the AHardwareBuffer in the passed in the following fields, if not NULL: 90 * width; - width in pixels 91 * height; - height in pixels 92 * layers; - number of images 93 * format; - One of AHARDWAREBUFFER_FORMAT_* 94 * usage; - Combination of AHARDWAREBUFFER_USAGE_* 95 * 96 */ 97 virtual void describe(const vk::pt::AndroidHardwareBufferPtr buffer, uint32_t *width, uint32_t *height, 98 uint32_t *layers, uint32_t *format, uint64_t *usage, uint32_t *stride) = 0; 99 100 /** 101 * Return a pointer to buffer data for CPU read. nullptr is returned on failure. 102 * Buffer must have been created with usage flags. 103 */ 104 virtual void *lock(vk::pt::AndroidHardwareBufferPtr buffer, uint64_t usage) = 0; 105 106 /** 107 * Returns TRUE if locking the buffer for buffer data for CPU read was successful, FALSE otherwise. 108 * Buffer must have been created with usage flags. 109 * Out parameters will be be filled with required data to access each plane according to planeCountOut. 110 * Plane 0 will have all data in planeDataOut[0], planeStrideOut[0], planeRowStrideOut[0] 111 * Plane 1 will have all data in planeDataOut[1], planeStrideOut[1], planeRowStrideOut[1] 112 * ... 113 * planeCount - number of planes present in buffer 114 * planeDataOut - array of pointers to plane data 115 * planePixelStrideOut - plane stride for each pixel in a row 116 * planeRowStrideOut - plane stride for each row 117 */ 118 virtual bool lockPlanes(vk::pt::AndroidHardwareBufferPtr buffer, uint64_t usage, uint32_t &planeCountOut, 119 void *planeDataOut[4], uint32_t planePixelStrideOut[4], uint32_t planeRowStrideOut[4]) = 0; 120 121 /** 122 * Returns TRUE if buffer was unlocked successfully from previous lock operations. 123 * FALSE is returned otherwise. 124 */ 125 virtual bool unlock(vk::pt::AndroidHardwareBufferPtr buffer) = 0; 126 127 virtual uint64_t vkUsageToAhbUsage(vk::VkImageUsageFlagBits vkFlag) = 0; 128 virtual uint64_t vkCreateToAhbUsage(vk::VkImageCreateFlagBits vkFlag) = 0; 129 virtual uint32_t vkFormatToAhbFormat(vk::VkFormat vkFormat) = 0; 130 virtual uint64_t mustSupportAhbUsageFlags() = 0; 131 virtual bool ahbFormatIsBlob(uint32_t format) = 0; 132 virtual bool ahbFormatIsYuv(uint32_t format) = 0; 133 134 /* Retrieves all present formats in AHB */ 135 virtual std::vector<uint32_t> getAllSupportedFormats() = 0; 136 137 /* AHB format as a string */ 138 virtual const char *getFormatAsString(uint32_t format) = 0; 139 140 virtual ~AndroidHardwareBufferExternalApi(); 141 142 protected: 143 // Protected Constructor 144 AndroidHardwareBufferExternalApi(); 145 146 private: 147 // Stop the compiler generating methods of copy the object 148 AndroidHardwareBufferExternalApi(AndroidHardwareBufferExternalApi const ©); // Not Implemented 149 AndroidHardwareBufferExternalApi &operator=(AndroidHardwareBufferExternalApi const ©); // Not Implemented 150 151 static bool loadAhbDynamicApis(int32_t sdkVersion); 152 }; 153 154 // Buffer class that allows CPU read/writes to Android Hardware Buffers 155 class AndroidHardwareBufferInstance 156 { 157 // Class/struct/enum/... definitions 158 public: 159 // Can check if format is supported using isFormatSupported 160 enum Format : uint32_t 161 { 162 // Formats exposed by Native Hardware Buffer API 163 R8G8B8A8_UNORM = 0, 164 R8G8B8X8_UNORM, 165 R8G8B8_UNORM, 166 R5G6B5_UNORM, 167 R16G16B16A16_FLOAT, 168 R10G10B10A2_UNORM, 169 BLOB, 170 D16_UNORM, 171 D24_UNORM, 172 D24_UNORM_S8_UINT, 173 D32_FLOAT, 174 D32_FLOAT_S8_UINT, // No CPU side validation available through AHB 175 S8_UINT, 176 Y8Cb8Cr8_420, 177 YCbCr_P010, 178 R8_UNORM, 179 R16_UINT, 180 R16G16_UINT, 181 R10G10B10A10_UNORM, 182 183 // Formats not exposed by Native Hardware Buffer API 184 // Present in Android Hardware Buffer 185 // Values obtained AOSP header (nativewindow/include/vndk/hardware_buffer.h) 186 B8G8R8A8_UNORM, 187 YV12, 188 Y8, 189 Y16, 190 RAW10, 191 RAW12, 192 RAW16, 193 RAW_OPAQUE, // No validation possible 194 IMPLEMENTATION_DEFINED, // No validation possible 195 NV16, // AHARDWAREBUFFER_FORMAT_YCbCr_422_SP 196 NV21, // AHARDWAREBUFFER_FORMAT_YCrCb_420_SP 197 YUY2, // AHARDWAREBUFFER_FORMAT_YCbCr_422_I 198 199 COUNT, 200 UNASSIGNED 201 }; 202 203 // Can be expanded as needed 204 enum Usage : uint32_t 205 { 206 UNUSED = 0, 207 GPU_FRAMEBUFFER = 1, 208 GPU_SAMPLED = 2, 209 CPU_READ = 4, 210 CPU_WRITE = 8, 211 }; 212 213 enum ChromaLocation : uint32_t 214 { 215 COSITED_EVEN = 0, // VK_CHROMA_LOCATION_COSITED_EVEN 216 MIDPOINT, // VK_CHROMA_LOCATION_MIDPOINT 217 }; 218 219 protected: 220 struct AccessDataCPU 221 { 222 uint32_t m_planeCount = 0u; 223 union 224 { 225 uint8_t *m_planeData[4] = {nullptr, nullptr, nullptr, nullptr}; 226 void *m_planeDataVoid[4]; 227 }; 228 uint32_t m_planePixelStride[4] = {0u, 0u, 0u, 0u}; 229 uint32_t m_planeRowStride[4] = {0u, 0u, 0u, 0u}; 230 }; 231 232 using AhbApi = AndroidHardwareBufferExternalApi; 233 using Handle = vk::pt::AndroidHardwareBufferPtr; 234 235 // Static functions 236 public: 237 static int32_t getSdkVersion(); 238 static bool isFormatSupported(Format format); 239 static bool isFormatYuv(Format format); 240 static bool isFormatRaw(Format format); 241 static bool isFormatColor(Format format); 242 static bool isFormatDepth(Format format); 243 static bool isFormatStencil(Format format); 244 static bool hasFormatAlpha(Format format); 245 static const char *getFormatName(Format format); 246 static uint32_t formatToInternalFormat(Format format); 247 static tcu::TextureFormat formatToTextureFormat(Format format); 248 static ChromaLocation vkChromaLocationToChromaLocation(vk::VkChromaLocation location); 249 static void reduceYuvTexture(tcu::TextureLevel &texture, Format format, ChromaLocation xChroma, 250 ChromaLocation yChroma); 251 252 protected: 253 static void reduceYuv420Texture(tcu::TextureLevel &texture, ChromaLocation xChroma, ChromaLocation yChroma); 254 static void reduceYuv422Texture(tcu::TextureLevel &texture, ChromaLocation xChroma); 255 static uint64_t usageToInternalUsage(Usage usage); 256 // Pixel stride in bytes 257 static uint32_t pixelStride(Format format); 258 259 // Member functions 260 public: 261 ~AndroidHardwareBufferInstance(void); 262 263 bool allocate(Format format, uint32_t width, uint32_t height, uint32_t layers, Usage usage); 264 void release(void); 265 266 bool lock(Usage usage); 267 bool unlock(void); 268 269 void copyCpuBufferToAndroidBuffer(const tcu::TextureLevel &cpuBuffer); 270 void copyCpuBufferToAndroidBufferCompressed(const tcu::CompressedTexture &cpuBuffer); 271 void copyAndroidBufferToCpuBuffer(tcu::TextureLevel &cpuBuffer) const; 272 void copyAndroidBufferToCpuBufferCompressed(tcu::CompressedTexture &cpuBuffer) const; 273 getAhbTextureFormat(void) const274 tcu::TextureFormat getAhbTextureFormat(void) const 275 { 276 return formatToTextureFormat(m_format); 277 }; getHandle(void) const278 Handle getHandle(void) const 279 { 280 return m_handle; 281 } 282 283 bool isYuv(void) const; 284 bool isRaw(void) const; 285 bool hasDepth(void) const; 286 bool hasStencil(void) const; 287 288 // Data 289 protected: 290 AccessDataCPU m_accessData; 291 AhbApi *m_ahbApi = AhbApi::getInstance(); 292 Handle m_handle = Handle(nullptr); 293 Usage m_usage = UNUSED; 294 uint64_t m_internalUsage = 0u; 295 Format m_format = UNASSIGNED; 296 uint32_t m_internalFormat = 0u; 297 uint32_t m_width = 0u; 298 uint32_t m_height = 0u; 299 uint32_t m_layers = 0u; 300 }; 301 302 } // namespace ExternalMemoryUtil 303 304 } // namespace vkt 305 306 #endif // CTS_USES_VULKANSC 307 308 #endif // _VKTEXTERNALMEMORYANDROIDHARDWAREBUFFERUTIL_HPP 309