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