xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkImageUtil.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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> &copyRegions, 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> &copyRegions,
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