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