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