1 #ifndef _VKIMAGEUTIL_HPP 2 #define _VKIMAGEUTIL_HPP 3 /*------------------------------------------------------------------------- 4 * Vulkan CTS Framework 5 * -------------------- 6 * 7 * Copyright (c) 2015 The Khronos Group Inc. 8 * Copyright (c) 2015 Imagination Technologies Ltd. 9 * Copyright (c) 2015 Google 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 Utilities for images. 26 *//*--------------------------------------------------------------------*/ 27 28 #include "vkDefs.hpp" 29 #include "tcuTexture.hpp" 30 #include "tcuCompressedTexture.hpp" 31 #include "deSharedPtr.hpp" 32 #include "vkImageWithMemory.hpp" 33 #include "vkBufferWithMemory.hpp" 34 #include "vkMemUtil.hpp" 35 #include "vkTypeUtil.hpp" 36 #include <memory> 37 38 namespace vk 39 { 40 41 bool isFloatFormat (VkFormat format); 42 bool isUfloatFormat (VkFormat format); 43 bool isSfloatFormat (VkFormat format); 44 bool isUnormFormat (VkFormat format); 45 bool isSnormFormat (VkFormat format); 46 bool isIntFormat (VkFormat format); 47 bool isUintFormat (VkFormat format); 48 bool isDepthStencilFormat (VkFormat format); 49 bool isCompressedFormat (VkFormat format); 50 bool isSrgbFormat (VkFormat format); 51 52 bool is64BitIntegerFormat (VkFormat format); 53 54 bool isSupportedByFramework (VkFormat format); 55 void checkImageSupport (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const VkImageCreateInfo& imageCreateInfo); 56 57 tcu::TextureFormat mapVkFormat (VkFormat format); 58 tcu::CompressedTexFormat mapVkCompressedFormat (VkFormat format); 59 tcu::TextureFormat getDepthCopyFormat (VkFormat combinedFormat); 60 tcu::TextureFormat getStencilCopyFormat (VkFormat combinedFormat); 61 62 tcu::Sampler mapVkSampler (const VkSamplerCreateInfo& samplerCreateInfo); 63 tcu::Sampler::CompareMode mapVkSamplerCompareOp (VkCompareOp compareOp); 64 tcu::Sampler::WrapMode mapVkSamplerAddressMode (VkSamplerAddressMode addressMode); 65 tcu::Sampler::ReductionMode mapVkSamplerReductionMode (VkSamplerReductionMode reductionMode); 66 tcu::Sampler::FilterMode mapVkMinTexFilter (VkFilter filter, VkSamplerMipmapMode mipMode); 67 tcu::Sampler::FilterMode mapVkMagTexFilter (VkFilter filter); 68 69 VkFilter mapFilterMode (tcu::Sampler::FilterMode filterMode); 70 VkSamplerMipmapMode mapMipmapMode (tcu::Sampler::FilterMode filterMode); 71 VkSamplerAddressMode mapWrapMode (tcu::Sampler::WrapMode wrapMode); 72 VkCompareOp mapCompareMode (tcu::Sampler::CompareMode mode); 73 VkFormat mapTextureFormat (const tcu::TextureFormat& format); 74 VkFormat mapCompressedTextureFormat (const tcu::CompressedTexFormat format); 75 VkSamplerCreateInfo mapSampler (const tcu::Sampler& sampler, const tcu::TextureFormat& format, float minLod = 0.0f, float maxLod = 1000.0f, bool unnormal = false); 76 rr::GenericVec4 mapVkColor (const VkClearColorValue& color); 77 VkClearColorValue mapVkColor (const rr::GenericVec4& color); 78 79 void imageUtilSelfTest (void); 80 81 float getRepresentableDiffUnorm (const VkFormat format, const deUint32 componentNdx); 82 float getRepresentableDiffSnorm (const VkFormat format, const deUint32 componentNdx); 83 deUint32 getFormatComponentWidth (const VkFormat format, const deUint32 componentNdx); 84 deUint32 getBlockSizeInBytes (const VkFormat compressedFormat); 85 deUint32 getBlockWidth (const VkFormat compressedFormat); 86 deUint32 getBlockHeight (const VkFormat compressedFormat); 87 88 bool hasSpirvFormat (VkFormat fmt); 89 const std::string getSpirvFormat (VkFormat fmt); 90 91 const deUint32 BUFFER_IMAGE_COPY_OFFSET_GRANULARITY = 4u; 92 93 // \todo [2017-05-18 pyry] Consider moving this to tcu 94 struct PlanarFormatDescription 95 { 96 enum 97 { 98 MAX_CHANNELS = 4, 99 MAX_PLANES = 3 100 }; 101 102 enum ChannelFlags 103 { 104 CHANNEL_R = (1u<<0), // Has "R" (0) channel 105 CHANNEL_G = (1u<<1), // Has "G" (1) channel 106 CHANNEL_B = (1u<<2), // Has "B" (2) channel 107 CHANNEL_A = (1u<<3), // Has "A" (3) channel 108 }; 109 110 struct Plane 111 { 112 deUint8 elementSizeBytes; 113 deUint8 widthDivisor; 114 deUint8 heightDivisor; 115 VkFormat planeCompatibleFormat; 116 }; 117 118 struct Channel 119 { 120 deUint8 planeNdx; 121 deUint8 type; // tcu::TextureChannelClass value 122 deUint8 offsetBits; // Offset in element in bits 123 deUint8 sizeBits; // Value size in bits 124 deUint8 strideBytes; // Pixel stride (in bytes), usually plane elementSize 125 }; 126 127 deUint8 numPlanes; 128 deUint8 presentChannels; 129 deUint8 blockWidth; 130 deUint8 blockHeight; 131 Plane planes[MAX_PLANES]; 132 Channel channels[MAX_CHANNELS]; 133 hasChannelNdxvk::PlanarFormatDescription134 inline bool hasChannelNdx (deUint32 ndx) const 135 { 136 DE_ASSERT(de::inBounds(ndx, 0u, 4u)); 137 return (presentChannels & (1u<<ndx)) != 0; 138 } 139 }; 140 141 class ImageWithBuffer { 142 std::unique_ptr<ImageWithMemory> image; 143 Move<vk::VkImageView> imageView; 144 std::unique_ptr<BufferWithMemory> buffer; 145 VkDeviceSize size; 146 147 public: 148 ImageWithBuffer( 149 const DeviceInterface& vkd, 150 const VkDevice device, 151 Allocator& alloc, 152 vk::VkExtent3D extent, 153 vk::VkFormat imageFormat, 154 vk::VkImageUsageFlags usage, 155 vk::VkImageType imageType, 156 vk::VkImageSubresourceRange ssr = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u), 157 uint32_t arrayLayers = 1, 158 vk::VkSampleCountFlagBits samples = VK_SAMPLE_COUNT_1_BIT, 159 vk::VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL, 160 uint32_t mipLevels = 1, 161 vk::VkSharingMode sharingMode = VK_SHARING_MODE_EXCLUSIVE); 162 163 VkImage getImage(); 164 VkImageView getImageView(); 165 VkBuffer getBuffer(); 166 VkDeviceSize getBufferSize(); 167 Allocation& getImageAllocation(); 168 Allocation& getBufferAllocation(); 169 }; 170 171 bool isYCbCrFormat (VkFormat format); 172 bool isYCbCrExtensionFormat (VkFormat format); 173 bool isYCbCrConversionFormat (VkFormat format); 174 PlanarFormatDescription getPlanarFormatDescription (VkFormat format); 175 int getPlaneCount (VkFormat format); 176 deUint32 getMipmapCount (VkFormat format, 177 const vk::PlanarFormatDescription& formatDescription, 178 const vk::VkImageFormatProperties& imageFormatProperties, 179 const vk::VkExtent3D& extent); 180 181 deUint32 getPlaneSizeInBytes (const PlanarFormatDescription& formatInfo, 182 const VkExtent3D& baseExtents, 183 const deUint32 planeNdx, 184 const deUint32 mipmapLevel, 185 const deUint32 mipmapMemoryAlignment); 186 deUint32 getPlaneSizeInBytes (const PlanarFormatDescription& formatInfo, 187 const tcu::UVec2& baseExtents, 188 const deUint32 planeNdx, 189 const deUint32 mipmapLevel, 190 const deUint32 mipmapMemoryAlignment); 191 VkExtent3D getPlaneExtent (const PlanarFormatDescription& formatInfo, 192 const VkExtent3D& baseExtents, 193 const deUint32 planeNdx, 194 const deUint32 mipmapLevel); 195 tcu::UVec2 getPlaneExtent (const PlanarFormatDescription& formatInfo, 196 const tcu::UVec2& baseExtents, 197 const deUint32 planeNdx, 198 const deUint32 mipmapLevel); 199 tcu::UVec3 getImageSizeAlignment (VkFormat format); 200 tcu::UVec3 getImageSizeAlignment (const PlanarFormatDescription& formatInfo); 201 tcu::UVec2 getBlockExtent (VkFormat format); 202 tcu::UVec2 getBlockExtent (const PlanarFormatDescription& formatInfo); 203 VkFormat getPlaneCompatibleFormat (VkFormat format, 204 deUint32 planeNdx); 205 VkFormat getPlaneCompatibleFormat (const PlanarFormatDescription& formatInfo, 206 deUint32 planeNdx); 207 208 VkImageAspectFlagBits getPlaneAspect (deUint32 planeNdx); 209 deUint32 getAspectPlaneNdx (VkImageAspectFlagBits planeAspect); 210 bool isChromaSubsampled (VkFormat format); 211 bool isYCbCr422Format (VkFormat format); 212 bool isYCbCr420Format (VkFormat format); 213 214 tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription& formatInfo, 215 const tcu::UVec2& size, 216 const deUint32* planeRowPitches, 217 void* const* planePtrs, 218 deUint32 channelNdx); 219 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription& formatInfo, 220 const tcu::UVec2& size, 221 const deUint32* planeRowPitches, 222 const void* const* planePtrs, 223 deUint32 channelNdx); 224 tcu::PixelBufferAccess getChannelAccess (const PlanarFormatDescription& formatInfo, 225 const tcu::UVec3& size, 226 const deUint32* planeRowPitches, 227 void* const* planePtrs, 228 deUint32 channelNdx); 229 tcu::ConstPixelBufferAccess getChannelAccess (const PlanarFormatDescription& formatInfo, 230 const tcu::UVec3& size, 231 const deUint32* planeRowPitches, 232 const void* const* planePtrs, 233 deUint32 channelNdx); 234 VkImageAspectFlags getImageAspectFlags (const tcu::TextureFormat textureFormat); 235 VkExtent3D mipLevelExtents (const VkExtent3D& baseExtents, 236 const deUint32 mipLevel); 237 tcu::UVec3 alignedDivide (const VkExtent3D& extent, 238 const VkExtent3D& divisor); 239 240 /*--------------------------------------------------------------------*//*! 241 * Copies buffer data into an image. The buffer is expected to be 242 * in a state after host write. 243 *//*--------------------------------------------------------------------*/ 244 void copyBufferToImage (const DeviceInterface& vk, 245 vk::VkDevice device, 246 vk::VkQueue queue, 247 deUint32 queueFamilyIndex, 248 const vk::VkBuffer& buffer, 249 vk::VkDeviceSize bufferSize, 250 const std::vector<vk::VkBufferImageCopy>& copyRegions, 251 const vk::VkSemaphore* waitSemaphore, 252 vk::VkImageAspectFlags imageAspectFlags, 253 deUint32 mipLevels, 254 deUint32 arrayLayers, 255 vk::VkImage destImage, 256 VkImageLayout destImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 257 VkPipelineStageFlags destImageDstStageFlags = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 258 const VkCommandPool* externalCommandPool = DE_NULL, 259 deUint32 baseMipLevel = 0); 260 261 void copyBufferToImage (const DeviceInterface& vk, 262 const VkCommandBuffer& cmdBuffer, 263 const VkBuffer& buffer, 264 vk::VkDeviceSize bufferSize, 265 const std::vector<VkBufferImageCopy>& copyRegions, 266 VkImageAspectFlags imageAspectFlags, 267 deUint32 mipLevels, 268 deUint32 arrayLayers, 269 VkImage destImage, 270 VkImageLayout destImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 271 VkPipelineStageFlags destImageDstStageFlags = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 272 deUint32 baseMipLevel = 0); 273 274 /*--------------------------------------------------------------------*//*! 275 * Copies image data into a buffer. The buffer is expected to be 276 * read by the host. 277 *//*--------------------------------------------------------------------*/ 278 void copyImageToBuffer (const DeviceInterface& vk, 279 vk::VkCommandBuffer cmdBuffer, 280 vk::VkImage image, 281 vk::VkBuffer buffer, 282 tcu::IVec2 size, 283 vk::VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 284 vk::VkImageLayout oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 285 deUint32 numLayers = 1u, 286 VkImageAspectFlags barrierAspect = VK_IMAGE_ASPECT_COLOR_BIT, 287 VkImageAspectFlags copyAspect = VK_IMAGE_ASPECT_COLOR_BIT, 288 VkPipelineStageFlags srcMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); 289 290 void copyImageToBuffer (const DeviceInterface& vk, 291 vk::VkCommandBuffer cmdBuffer, 292 vk::VkImage image, 293 vk::VkBuffer buffer, 294 vk::VkFormat format, 295 tcu::IVec2 size, 296 deUint32 mipLevel = 0u, 297 vk::VkAccessFlags srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 298 vk::VkImageLayout oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 299 deUint32 numLayers = 1u, 300 VkImageAspectFlags barrierAspect = VK_IMAGE_ASPECT_COLOR_BIT, 301 VkImageAspectFlags copyAspect = VK_IMAGE_ASPECT_COLOR_BIT); 302 303 /*--------------------------------------------------------------------*//*! 304 * Clear a color image 305 *//*--------------------------------------------------------------------*/ 306 void clearColorImage (const DeviceInterface& vk, 307 const vk::VkDevice device, 308 const vk::VkQueue queue, 309 deUint32 queueFamilyIndex, 310 vk::VkImage image, 311 tcu::Vec4 clearColor, 312 vk::VkImageLayout oldLayout, 313 vk::VkImageLayout newLayout, 314 vk::VkPipelineStageFlags dstStageFlags, 315 deUint32 baseArrayLayer = 0u, 316 deUint32 layerCount = 1u, 317 deUint32 baseMipLevel = 0u, 318 deUint32 levelCount = 1u); 319 320 void clearColorImage (const DeviceInterface& vk, 321 const vk::VkDevice device, 322 const vk::VkQueue queue, 323 deUint32 queueFamilyIndex, 324 vk::VkImage image, 325 vk::VkClearColorValue clearColor, 326 vk::VkImageLayout oldLayout, 327 vk::VkImageLayout newLayout, 328 vk::VkAccessFlags dstAccessFlags, 329 vk::VkPipelineStageFlags dstStageFlags, 330 deUint32 baseArrayLayer = 0u, 331 deUint32 layerCount = 1u, 332 deUint32 baseMipLevel = 0u, 333 deUint32 levelCount = 1u); 334 335 /*--------------------------------------------------------------------*//*! 336 * Initialize color image with a chessboard pattern 337 *//*--------------------------------------------------------------------*/ 338 void initColorImageChessboardPattern (const DeviceInterface& vk, 339 const vk::VkDevice device, 340 const vk::VkQueue queue, 341 deUint32 queueFamilyIndex, 342 Allocator& allocator, 343 vk::VkImage image, 344 vk::VkFormat format, 345 tcu::Vec4 colorValue0, 346 tcu::Vec4 colorValue1, 347 deUint32 imageWidth, 348 deUint32 imageHeight, 349 deUint32 tileSize, 350 vk::VkImageLayout oldLayout, 351 vk::VkImageLayout newLayout, 352 vk::VkPipelineStageFlags dstStageFlags); 353 354 /*--------------------------------------------------------------------*//*! 355 * Copies depth/stencil image data into two separate buffers. 356 * The buffers are expected to be read by the host. 357 *//*--------------------------------------------------------------------*/ 358 void copyDepthStencilImageToBuffers (const DeviceInterface& vk, 359 vk::VkCommandBuffer cmdBuffer, 360 vk::VkImage image, 361 vk::VkBuffer depthBuffer, 362 vk::VkBuffer stencilBuffer, 363 tcu::IVec2 size, 364 vk::VkAccessFlags srcAccessMask, 365 vk::VkImageLayout oldLayout, 366 deUint32 numLayers = 1u); 367 368 /*--------------------------------------------------------------------*//*! 369 * Clear a depth/stencil image 370 *//*--------------------------------------------------------------------*/ 371 void clearDepthStencilImage (const DeviceInterface& vk, 372 const vk::VkDevice device, 373 const vk::VkQueue queue, 374 deUint32 queueFamilyIndex, 375 vk::VkImage image, 376 vk::VkFormat format, 377 float depthValue, 378 deUint32 stencilValue, 379 vk::VkImageLayout oldLayout, 380 vk::VkImageLayout newLayout, 381 vk::VkAccessFlags dstAccessFlags, 382 vk::VkPipelineStageFlags dstStageFlags); 383 384 /*--------------------------------------------------------------------*//*! 385 * Initialize depth and stencil channels with a chessboard pattern 386 *//*--------------------------------------------------------------------*/ 387 void initDepthStencilImageChessboardPattern (const DeviceInterface& vk, 388 const vk::VkDevice device, 389 const vk::VkQueue queue, 390 deUint32 queueFamilyIndex, 391 Allocator& allocator, 392 vk::VkImage image, 393 vk::VkFormat format, 394 float depthValue0, 395 float depthValue1, 396 deUint32 stencilValue0, 397 deUint32 stencilValue1, 398 deUint32 imageWidth, 399 deUint32 imageHeight, 400 deUint32 tileSize, 401 vk::VkImageLayout oldLayout, 402 vk::VkImageLayout newLayout, 403 vk::VkPipelineStageFlags dstStageFlags); 404 405 /*--------------------------------------------------------------------*//*! 406 * Makes common image subresource structures with common defaults 407 *//*--------------------------------------------------------------------*/ 408 vk::VkImageSubresourceRange makeDefaultImageSubresourceRange(); 409 410 vk::VkImageSubresourceLayers makeDefaultImageSubresourceLayers(); 411 412 #ifndef CTS_USES_VULKANSC 413 /*--------------------------------------------------------------------*//*! 414 * Checks if the physical device supports creation of the specified 415 * image format. 416 *//*--------------------------------------------------------------------*/ 417 bool checkSparseImageFormatSupport (const VkPhysicalDevice physicalDevice, 418 const InstanceInterface& instance, 419 const VkFormat format, 420 const VkImageType imageType, 421 const VkSampleCountFlagBits sampleCount, 422 const VkImageUsageFlags usageFlags, 423 const VkImageTiling imageTiling); 424 425 bool checkSparseImageFormatSupport (const vk::VkPhysicalDevice physicalDevice, 426 const vk::InstanceInterface& instance, 427 const vk::VkImageCreateInfo& imageCreateInfo); 428 429 /*--------------------------------------------------------------------*//*! 430 * Allocates memory for a sparse image and handles the memory binding. 431 *//*--------------------------------------------------------------------*/ 432 void allocateAndBindSparseImage (const vk::DeviceInterface& vk, 433 vk::VkDevice device, 434 const vk::VkPhysicalDevice physicalDevice, 435 const vk::InstanceInterface& instance, 436 const vk::VkImageCreateInfo& imageCreateInfo, 437 const vk::VkSemaphore& signalSemaphore, 438 vk::VkQueue queue, 439 vk::Allocator& allocator, 440 std::vector<de::SharedPtr<vk::Allocation> >& allocations, 441 tcu::TextureFormat format, 442 vk::VkImage destImage); 443 #endif // CTS_USES_VULKANSC 444 } // vk 445 446 #endif // _VKIMAGEUTIL_HPP 447