• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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