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