1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file  vktImageTranscodingSupportTests.cpp
21  * \brief Transcoding support tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktImageTranscodingSupportTests.hpp"
25 
26 #include "deUniquePtr.hpp"
27 #include "deStringUtil.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deRandom.hpp"
30 
31 #include "vktTestCaseUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vktImageTestsUtil.hpp"
35 #include "vkBarrierUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 
43 #include "tcuTextureUtil.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuCompressedTexture.hpp"
46 #include "tcuVectorType.hpp"
47 #include "tcuResource.hpp"
48 #include "tcuImageIO.hpp"
49 #include "tcuImageCompare.hpp"
50 #include "tcuTestLog.hpp"
51 #include "tcuRGBA.hpp"
52 #include "tcuSurface.hpp"
53 
54 #include <vector>
55 #include <iomanip>
56 
57 using namespace vk;
58 namespace vkt
59 {
60 namespace image
61 {
62 namespace
63 {
64 using std::string;
65 using std::vector;
66 using tcu::TestContext;
67 using tcu::TestStatus;
68 using tcu::UVec3;
69 using tcu::IVec3;
70 using tcu::CompressedTexFormat;
71 using tcu::CompressedTexture;
72 using tcu::Resource;
73 using tcu::Archive;
74 using tcu::ConstPixelBufferAccess;
75 using de::MovePtr;
76 using de::SharedPtr;
77 using de::Random;
78 
79 enum Operation
80 {
81 	OPERATION_ATTACHMENT_READ,
82 	OPERATION_ATTACHMENT_WRITE,
83 	OPERATION_TEXTURE_READ,
84 	OPERATION_TEXTURE_WRITE,
85 	OPERATION_LAST
86 };
87 
88 struct TestParameters
89 {
90 	Operation				operation;
91 	UVec3					size;
92 	ImageType				imageType;
93 	VkImageUsageFlagBits	testedImageUsageFeature;
94 	VkFormat				featuredFormat;
95 	VkFormat				featurelessFormat;
96 	VkImageUsageFlags		testedImageUsage;
97 	VkImageUsageFlags		pairedImageUsage;
98 	const VkFormat*			compatibleFormats;
99 };
100 
101 const deUint32 SINGLE_LEVEL = 1u;
102 const deUint32 SINGLE_LAYER = 1u;
103 
104 class BasicTranscodingTestInstance : public TestInstance
105 {
106 public:
107 							BasicTranscodingTestInstance	(Context&				context,
108 															 const TestParameters&	parameters);
109 	virtual TestStatus		iterate							(void) = 0;
110 protected:
111 	void					generateData					(deUint8*				toFill,
112 															 size_t					size,
113 															 const VkFormat			format = VK_FORMAT_UNDEFINED);
114 	const TestParameters	m_parameters;
115 };
116 
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)117 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
118 	: TestInstance	(context)
119 	, m_parameters	(parameters)
120 {
121 }
122 
generateData(deUint8 * toFill,size_t size,const VkFormat format)123 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
124 {
125 	const deUint8 pattern[] =
126 	{
127 		// 64-bit values
128 		0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
129 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
131 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
132 		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
133 		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
134 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
135 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
136 		0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
137 		0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
138 		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Positive infinity
139 		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Negative infinity
140 		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
141 		0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
142 		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
143 		0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
144 		0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
145 		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of of a quiet NaN (NANQ)
146 		0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
147 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a quiet NaN (NANQ)
148 		// 32-bit values
149 		0x7F, 0x80, 0x00, 0x00,								// Positive infinity
150 		0xFF, 0x80, 0x00, 0x00,								// Negative infinity
151 		0x7F, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
152 		0x7F, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
153 		0xFF, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
154 		0xFF, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
155 		0x7F, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
156 		0x7F, 0xFF, 0xFF, 0xFF,								// End of of a quiet NaN (NANQ)
157 		0xFF, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
158 		0xFF, 0xFF, 0xFF, 0xFF,								// End of a quiet NaN (NANQ)
159 		0xAA, 0xAA, 0xAA, 0xAA,
160 		0x55, 0x55, 0x55, 0x55,
161 	};
162 
163 	deUint8*	start		= toFill;
164 	size_t		sizeToRnd	= size;
165 
166 	// Pattern part
167 	if (size >= 2 * sizeof(pattern))
168 	{
169 		// Rotated pattern
170 		for (size_t i = 0; i < sizeof(pattern); i++)
171 			start[sizeof(pattern) - i - 1] = pattern[i];
172 
173 		start		+= sizeof(pattern);
174 		sizeToRnd	-= sizeof(pattern);
175 
176 		// Direct pattern
177 		deMemcpy(start, pattern, sizeof(pattern));
178 
179 		start		+= sizeof(pattern);
180 		sizeToRnd	-= sizeof(pattern);
181 	}
182 
183 	// Random part
184 	{
185 		DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
186 
187 		deUint32*	start32		= reinterpret_cast<deUint32*>(start);
188 		size_t		sizeToRnd32	= sizeToRnd / sizeof(deUint32);
189 		Random		rnd			(static_cast<deUint32>(format));
190 
191 		for (size_t i = 0; i < sizeToRnd32; i++)
192 			start32[i] = rnd.getUint32();
193 	}
194 
195 	{
196 		// Remove certain values that may not be preserved based on the uncompressed view format
197 		if (isSnormFormat(m_parameters.featuredFormat))
198 		{
199 			tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
200 
201 			if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
202 			{
203 				for (size_t i = 0; i < size; i++)
204 				{
205 					// SNORM fix: due to write operation in SNORM format
206 					// replaces 0x80 to 0x81, remove these values from test
207 					if (toFill[i] == 0x80)
208 						toFill[i] = 0x81;
209 				}
210 			}
211 			else
212 			{
213 				for (size_t i = 0; i < size; i += 2)
214 				{
215 					// SNORM fix: due to write operation in SNORM format
216 					// replaces 0x00 0x80 to 0x01 0x80
217 					if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
218 						toFill[i+1] = 0x81;
219 				}
220 			}
221 		}
222 		else if (isFloatFormat(m_parameters.featuredFormat))
223 		{
224 			tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
225 
226 			if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
227 			{
228 				for (size_t i = 0; i < size; i += 2)
229 				{
230 					// HALF_FLOAT fix: remove INF and NaN
231 					if ((toFill[i+1] & 0x7C) == 0x7C)
232 						toFill[i+1] = 0x00;
233 				}
234 			}
235 			else if (textureFormat.type == tcu::TextureFormat::FLOAT)
236 			{
237 				for (size_t i = 0; i < size; i += 4)
238 				{
239 					// HALF_FLOAT fix: remove INF and NaN
240 					if ((toFill[i+1] & 0x7C) == 0x7C)
241 						toFill[i+1] = 0x00;
242 				}
243 
244 				for (size_t i = 0; i < size; i += 4)
245 				{
246 					// FLOAT fix: remove INF, NaN, and denorm
247 					// Little endian fix
248 					if (((toFill[i+3] & 0x7F) == 0x7F && (toFill[i+2] & 0x80) == 0x80) || ((toFill[i+3] & 0x7F) == 0x00 && (toFill[i+2] & 0x80) == 0x00))
249 						toFill[i+3] = 0x01;
250 					// Big endian fix
251 					if (((toFill[i+0] & 0x7F) == 0x7F && (toFill[i+1] & 0x80) == 0x80) || ((toFill[i+0] & 0x7F) == 0x00 && (toFill[i+1] & 0x80) == 0x00))
252 						toFill[i+0] = 0x01;
253 				}
254 			}
255 		}
256 	}
257 }
258 
259 class GraphicsAttachmentsTestInstance : public BasicTranscodingTestInstance
260 {
261 public:
262 									GraphicsAttachmentsTestInstance	(Context& context, const TestParameters& parameters);
263 	virtual TestStatus				iterate							(void);
264 
265 protected:
266 	VkImageCreateInfo				makeCreateImageInfo				(const VkFormat				format,
267 																	 const ImageType			type,
268 																	 const UVec3&				size,
269 																	 const VkImageUsageFlags	usageFlags,
270 																	 const bool					extendedImageCreateFlag);
271 	VkImageViewUsageCreateInfo	makeImageViewUsageCreateInfo		(VkImageUsageFlags			imageUsageFlags);
272 	VkDeviceSize					getUncompressedImageData		(const VkFormat				format,
273 																	 const UVec3&				size,
274 																	 std::vector<deUint8>&		data);
275 	virtual void					transcode						(std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
276 	bool							compareAndLog					(const void* reference, const void* result, size_t size);
277 };
278 
GraphicsAttachmentsTestInstance(Context & context,const TestParameters & parameters)279 GraphicsAttachmentsTestInstance::GraphicsAttachmentsTestInstance (Context& context, const TestParameters& parameters)
280 	: BasicTranscodingTestInstance(context, parameters)
281 {
282 }
283 
iterate(void)284 TestStatus GraphicsAttachmentsTestInstance::iterate (void)
285 {
286 	std::vector<deUint8>	srcData;
287 	std::vector<deUint8>	dstData;
288 	de::MovePtr<Image>		outputImage;
289 
290 	transcode(srcData, dstData, outputImage);
291 
292 	DE_ASSERT(srcData.size() > 0 && srcData.size() == dstData.size());
293 
294 	if (!compareAndLog(&srcData[0], &dstData[0], srcData.size()))
295 		return TestStatus::fail("Output differs from input");
296 
297 	return TestStatus::pass("Pass");
298 }
299 
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)300 void GraphicsAttachmentsTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
301 {
302 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
303 	const VkDevice							device					= m_context.getDevice();
304 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
305 	const VkQueue							queue					= m_context.getUniversalQueue();
306 	Allocator&								allocator				= m_context.getDefaultAllocator();
307 
308 	const VkImageSubresourceRange			subresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
309 	const VkImageViewUsageCreateInfo*		imageViewUsageNull		= (VkImageViewUsageCreateInfo*)DE_NULL;
310 	const VkImageViewUsageCreateInfo		imageViewUsage			= makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
311 
312 	const VkFormat							srcFormat				= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.featurelessFormat :
313 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featuredFormat :
314 																	  VK_FORMAT_UNDEFINED;
315 	const bool								srcExtendedImageCreate	= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? true :
316 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? false :
317 																	  false;
318 	const VkImageUsageFlags					srcImageUsageFlags		= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.testedImageUsage :
319 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.pairedImageUsage :
320 																	  0;
321 	const VkImageViewUsageCreateInfo*		srcImageViewUsageFlags	= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? &imageViewUsage :
322 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? imageViewUsageNull :
323 																	  imageViewUsageNull;
324 	const VkDeviceSize						srcImageSizeInBytes		= getUncompressedImageData(srcFormat, m_parameters.size, srcData);
325 
326 	const VkFormat							dstFormat				= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.featuredFormat :
327 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.featurelessFormat :
328 																	  VK_FORMAT_UNDEFINED;
329 	const bool								dstExtendedImageCreate	= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? false :
330 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? true :
331 																	  false;
332 	const VkImageUsageFlags					dstImageUsageFlags		= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? m_parameters.pairedImageUsage :
333 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? m_parameters.testedImageUsage :
334 																	  0;
335 	const VkImageViewUsageCreateInfo*		dstImageViewUsageFlags	= (m_parameters.operation == OPERATION_ATTACHMENT_READ)  ? imageViewUsageNull :
336 																	  (m_parameters.operation == OPERATION_ATTACHMENT_WRITE) ? &imageViewUsage :
337 																	  imageViewUsageNull;
338 	const VkDeviceSize						dstImageSizeInBytes		= getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
339 
340 	const std::vector<tcu::Vec4>			vertexArray				= createFullscreenQuad();
341 	const deUint32							vertexCount				= static_cast<deUint32>(vertexArray.size());
342 	const size_t							vertexBufferSizeInBytes	= vertexCount * sizeof(vertexArray[0]);
343 	const MovePtr<Buffer>					vertexBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
344 	const Allocation&						vertexBufferAlloc		= vertexBuffer->getAllocation();
345 	const VkDeviceSize						vertexBufferOffset[]	= { 0 };
346 
347 	const VkBufferCreateInfo				srcImageBufferInfo		(makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
348 	const MovePtr<Buffer>					srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
349 
350 	const VkImageCreateInfo					srcImageCreateInfo		= makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
351 	const MovePtr<Image>					srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
352 	Move<VkImageView>						srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsageFlags));
353 
354 	const VkImageCreateInfo					dstImageCreateInfo		= makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
355 	de::MovePtr<Image>						dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
356 	Move<VkImageView>						dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsageFlags));
357 
358 	const VkBufferCreateInfo				dstImageBufferInfo		(makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
359 	MovePtr<Buffer>							dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
360 
361 	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
362 	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
363 
364 	const Unique<VkRenderPass>				renderPass				(makeRenderPass(vk, device, m_parameters.featuredFormat, m_parameters.featuredFormat));
365 
366 	const Move<VkDescriptorSetLayout>		descriptorSetLayout		(DescriptorSetLayoutBuilder()
367 																		.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT)
368 																		.build(vk, device));
369 	const Move<VkDescriptorPool>			descriptorPool			(DescriptorPoolBuilder()
370 																		.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, SINGLE_LAYER)
371 																		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, SINGLE_LAYER));
372 	const Move<VkDescriptorSet>				descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
373 	const VkDescriptorImageInfo				descriptorSrcImageInfo	(makeDescriptorImageInfo(DE_NULL, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
374 
375 	const VkExtent2D						renderSize				(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
376 	const Unique<VkPipelineLayout>			pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
377 	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 1u));
378 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
379 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
380 
381 	const VkBufferImageCopy					srcCopyRegion			= makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
382 	const VkBufferMemoryBarrier				srcCopyBufferBarrierPre	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
383 	const VkImageMemoryBarrier				srcCopyImageBarrierPre	= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, srcImage->get(), subresourceRange);
384 	const VkImageMemoryBarrier				srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
385 	const VkBufferImageCopy					dstCopyRegion			= makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
386 
387 	const VkImageView						attachmentBindInfos[]	= { *srcImageView, *dstImageView };
388 	const Move<VkFramebuffer>				framebuffer				(makeFramebuffer(vk, device, *renderPass, DE_LENGTH_OF_ARRAY(attachmentBindInfos), attachmentBindInfos, renderSize, SINGLE_LAYER));
389 
390 	DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
391 
392 	// Upload vertex data
393 	deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
394 	flushAlloc(vk, device, vertexBufferAlloc);
395 
396 	// Upload source image data
397 	const Allocation& alloc = srcImageBuffer->getAllocation();
398 	deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
399 	flushAlloc(vk, device, alloc);
400 
401 	beginCommandBuffer(vk, *cmdBuffer);
402 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
403 
404 	//Copy buffer to image
405 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrierPre, 1u, &srcCopyImageBarrierPre);
406 	vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &srcCopyRegion);
407 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &srcCopyImageBarrierPost);
408 
409 	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
410 
411 	DescriptorSetUpdateBuilder()
412 		.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorSrcImageInfo)
413 		.update(vk, device);
414 
415 	vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
416 	vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
417 	vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
418 
419 	endRenderPass(vk, *cmdBuffer);
420 
421 	const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
422 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
423 		VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
424 		dstImage->get(), subresourceRange);
425 
426 	const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
427 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
428 		dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
429 
430 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
431 	vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
432 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
433 
434 	endCommandBuffer(vk, *cmdBuffer);
435 
436 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
437 
438 	const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
439 	invalidateAlloc(vk, device, dstImageBufferAlloc);
440 	dstData.resize((size_t)dstImageSizeInBytes);
441 	deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
442 
443 	outputImage = dstImage;
444 }
445 
446 
makeCreateImageInfo(const VkFormat format,const ImageType type,const UVec3 & size,const VkImageUsageFlags usageFlags,const bool extendedImageCreateFlag)447 VkImageCreateInfo GraphicsAttachmentsTestInstance::makeCreateImageInfo (const VkFormat				format,
448 																		const ImageType				type,
449 																		const UVec3&				size,
450 																		const VkImageUsageFlags		usageFlags,
451 																		const bool					extendedImageCreateFlag)
452 {
453 	const VkImageType			imageType				= mapImageType(type);
454 	const VkImageCreateFlags	imageCreateFlagsBase	= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
455 	const VkImageCreateFlags	imageCreateFlagsAddOn	= extendedImageCreateFlag ? VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR : 0;
456 	const VkImageCreateFlags	imageCreateFlags		= imageCreateFlagsBase | imageCreateFlagsAddOn;
457 
458 	const VkImageCreateInfo createImageInfo =
459 	{
460 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	// VkStructureType			sType;
461 		DE_NULL,								// const void*				pNext;
462 		imageCreateFlags,						// VkImageCreateFlags		flags;
463 		imageType,								// VkImageType				imageType;
464 		format,									// VkFormat					format;
465 		makeExtent3D(getLayerSize(type, size)),	// VkExtent3D				extent;
466 		1u,										// deUint32					mipLevels;
467 		1u,										// deUint32					arrayLayers;
468 		VK_SAMPLE_COUNT_1_BIT,					// VkSampleCountFlagBits	samples;
469 		VK_IMAGE_TILING_OPTIMAL,				// VkImageTiling			tiling;
470 		usageFlags,								// VkImageUsageFlags		usage;
471 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode			sharingMode;
472 		0u,										// deUint32					queueFamilyIndexCount;
473 		DE_NULL,								// const deUint32*			pQueueFamilyIndices;
474 		VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			initialLayout;
475 	};
476 
477 	return createImageInfo;
478 }
479 
makeImageViewUsageCreateInfo(VkImageUsageFlags imageUsageFlags)480 VkImageViewUsageCreateInfo GraphicsAttachmentsTestInstance::makeImageViewUsageCreateInfo (VkImageUsageFlags imageUsageFlags)
481 {
482 	VkImageViewUsageCreateInfo imageViewUsageCreateInfo =
483 	{
484 		VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR,	//VkStructureType		sType;
485 		DE_NULL,											//const void*			pNext;
486 		imageUsageFlags,									//VkImageUsageFlags		usage;
487 	};
488 
489 	return imageViewUsageCreateInfo;
490 }
491 
getUncompressedImageData(const VkFormat format,const UVec3 & size,std::vector<deUint8> & data)492 VkDeviceSize GraphicsAttachmentsTestInstance::getUncompressedImageData (const VkFormat format, const UVec3& size, std::vector<deUint8>& data)
493 {
494 	tcu::IVec3				sizeAsIVec3	= tcu::IVec3(static_cast<int>(size[0]), static_cast<int>(size[1]), static_cast<int>(size[2]));
495 	VkDeviceSize			sizeBytes	= getImageSizeBytes(sizeAsIVec3, format);
496 
497 	data.resize((size_t)sizeBytes);
498 	generateData(&data[0], data.size(), format);
499 
500 	return sizeBytes;
501 }
502 
compareAndLog(const void * reference,const void * result,size_t size)503 bool GraphicsAttachmentsTestInstance::compareAndLog (const void* reference, const void* result, size_t size)
504 {
505 	tcu::TestLog&	log			= m_context.getTestContext().getLog();
506 
507 	const deUint64*	ref64	= reinterpret_cast<const deUint64*>(reference);
508 	const deUint64*	res64	= reinterpret_cast<const deUint64*>(result);
509 	const size_t	sizew	= size / sizeof(deUint64);
510 	bool			equal	= true;
511 
512 	DE_ASSERT(size % sizeof(deUint64) == 0);
513 
514 	for (deUint32 ndx = 0u; ndx < static_cast<deUint32>(sizew); ndx++)
515 	{
516 		if (ref64[ndx] != res64[ndx])
517 		{
518 			std::stringstream str;
519 
520 			str	<< "Difference begins near byte " << ndx * sizeof(deUint64) << "."
521 				<< " reference value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << ref64[ndx]
522 				<< " result value: 0x" << std::hex << std::setw(2ull * sizeof(deUint64)) << std::setfill('0') << res64[ndx];
523 
524 			log.writeMessage(str.str().c_str());
525 
526 			equal = false;
527 
528 			break;
529 		}
530 	}
531 
532 	return equal;
533 }
534 
535 
536 class GraphicsTextureTestInstance : public GraphicsAttachmentsTestInstance
537 {
538 public:
539 						GraphicsTextureTestInstance		(Context& context, const TestParameters& parameters);
540 
541 protected:
542 	void				transcode						(std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage);
543 };
544 
GraphicsTextureTestInstance(Context & context,const TestParameters & parameters)545 GraphicsTextureTestInstance::GraphicsTextureTestInstance (Context& context, const TestParameters& parameters)
546 	: GraphicsAttachmentsTestInstance(context, parameters)
547 {
548 }
549 
transcode(std::vector<deUint8> & srcData,std::vector<deUint8> & dstData,de::MovePtr<Image> & outputImage)550 void GraphicsTextureTestInstance::transcode (std::vector<deUint8>& srcData, std::vector<deUint8>& dstData, de::MovePtr<Image>& outputImage)
551 {
552 	const DeviceInterface&					vk						= m_context.getDeviceInterface();
553 	const VkDevice							device					= m_context.getDevice();
554 	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
555 	const VkQueue							queue					= m_context.getUniversalQueue();
556 	Allocator&								allocator				= m_context.getDefaultAllocator();
557 
558 	const VkImageSubresourceRange			subresourceRange		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, SINGLE_LEVEL, 0u, SINGLE_LAYER);
559 	const VkImageViewUsageCreateInfo*		imageViewUsageNull		= (VkImageViewUsageCreateInfo*)DE_NULL;
560 	const VkImageViewUsageCreateInfo		imageViewUsage			= makeImageViewUsageCreateInfo(m_parameters.testedImageUsage);
561 
562 	const VkFormat							srcFormat				= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.featurelessFormat :
563 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featuredFormat :
564 																	  VK_FORMAT_UNDEFINED;
565 	const bool								srcExtendedImageCreate	= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? true :
566 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? false :
567 																	  false;
568 	const VkImageUsageFlags					srcImageUsageFlags		= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.testedImageUsage :
569 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.pairedImageUsage :
570 																	  0;
571 	const VkImageViewUsageCreateInfo*		srcImageViewUsage		= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? &imageViewUsage :
572 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? imageViewUsageNull :
573 																	  imageViewUsageNull;
574 	const VkDeviceSize						srcImageSizeInBytes		= getUncompressedImageData(srcFormat, m_parameters.size, srcData);
575 
576 	const VkFormat							dstFormat				= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.featuredFormat :
577 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.featurelessFormat :
578 																	  VK_FORMAT_UNDEFINED;
579 	const bool								dstExtendedImageCreate	= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? false :
580 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? true :
581 																	  false;
582 	const VkImageUsageFlags					dstImageUsageFlags		= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? m_parameters.pairedImageUsage :
583 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? m_parameters.testedImageUsage :
584 																	  0;
585 	const VkImageViewUsageCreateInfo*		dstImageViewUsage		= (m_parameters.operation == OPERATION_TEXTURE_READ)  ? imageViewUsageNull :
586 																	  (m_parameters.operation == OPERATION_TEXTURE_WRITE) ? &imageViewUsage :
587 																	  imageViewUsageNull;
588 	const VkDeviceSize						dstImageSizeInBytes		= getUncompressedImageSizeInBytes(dstFormat, m_parameters.size);
589 
590 	const std::vector<tcu::Vec4>			vertexArray				= createFullscreenQuad();
591 	const deUint32							vertexCount				= static_cast<deUint32>(vertexArray.size());
592 	const size_t							vertexBufferSizeInBytes	= vertexCount * sizeof(vertexArray[0]);
593 	const MovePtr<Buffer>					vertexBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
594 	const Allocation&						vertexBufferAlloc		= vertexBuffer->getAllocation();
595 	const VkDeviceSize						vertexBufferOffset[]	= { 0 };
596 
597 	const VkBufferCreateInfo				srcImageBufferInfo		(makeBufferCreateInfo(srcImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_SRC_BIT));
598 	const MovePtr<Buffer>					srcImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, srcImageBufferInfo, MemoryRequirement::HostVisible));
599 
600 	const VkImageCreateInfo					srcImageCreateInfo		= makeCreateImageInfo(srcFormat, m_parameters.imageType, m_parameters.size, srcImageUsageFlags, srcExtendedImageCreate);
601 	const MovePtr<Image>					srcImage				(new Image(vk, device, allocator, srcImageCreateInfo, MemoryRequirement::Any));
602 	Move<VkImageView>						srcImageView			(makeImageView(vk, device, srcImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, srcImageViewUsage));
603 
604 	const VkImageCreateInfo					dstImageCreateInfo		= makeCreateImageInfo(dstFormat, m_parameters.imageType, m_parameters.size, dstImageUsageFlags, dstExtendedImageCreate);
605 	de::MovePtr<Image>						dstImage				(new Image(vk, device, allocator, dstImageCreateInfo, MemoryRequirement::Any));
606 	Move<VkImageView>						dstImageView			(makeImageView(vk, device, dstImage->get(), mapImageViewType(m_parameters.imageType), m_parameters.featuredFormat, subresourceRange, dstImageViewUsage));
607 	const VkImageMemoryBarrier				dstCopyImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, dstImage->get(), subresourceRange);
608 
609 	const VkBufferCreateInfo				dstImageBufferInfo		(makeBufferCreateInfo(dstImageSizeInBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT));
610 	MovePtr<Buffer>							dstImageBuffer			= MovePtr<Buffer>(new Buffer(vk, device, allocator, dstImageBufferInfo, MemoryRequirement::HostVisible));
611 
612 	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
613 	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0));
614 
615 	const Unique<VkRenderPass>				renderPass				(makeRenderPass(vk, device));
616 
617 	const Move<VkDescriptorSetLayout>		descriptorSetLayout		(DescriptorSetLayoutBuilder()
618 																		.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT)
619 																		.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT)
620 																		.build(vk, device));
621 	const Move<VkDescriptorPool>			descriptorPool			(DescriptorPoolBuilder()
622 																		.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
623 																		.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
624 																		.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
625 	const Move<VkDescriptorSet>				descriptorSet			(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout));
626 	const VkSamplerCreateInfo				srcSamplerInfo			(makeSamplerCreateInfo());
627 	const Move<VkSampler>					srcSampler				= vk::createSampler(vk, device, &srcSamplerInfo);
628 	const VkDescriptorImageInfo				descriptorSrcImage		(makeDescriptorImageInfo(*srcSampler, *srcImageView, VK_IMAGE_LAYOUT_GENERAL));
629 	const VkDescriptorImageInfo				descriptorDstImage		(makeDescriptorImageInfo(DE_NULL, *dstImageView, VK_IMAGE_LAYOUT_GENERAL));
630 
631 	const VkExtent2D						renderSize				(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
632 	const Unique<VkPipelineLayout>			pipelineLayout			(makePipelineLayout(vk, device, *descriptorSetLayout));
633 	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertShaderModule, *fragShaderModule, renderSize, 0u));
634 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, device, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT, queueFamilyIndex));
635 	const Unique<VkCommandBuffer>			cmdBuffer				(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
636 
637 	const VkBufferImageCopy					srcCopyRegion			= makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
638 	const VkBufferMemoryBarrier				srcCopyBufferBarrier	= makeBufferMemoryBarrier(VK_ACCESS_HOST_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, srcImageBuffer->get(), 0ull, srcImageSizeInBytes);
639 	const VkImageMemoryBarrier				srcCopyImageBarrier		= makeImageMemoryBarrier(0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
640 	const VkImageMemoryBarrier				srcCopyImageBarrierPost	= makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, srcImage->get(), subresourceRange);
641 
642 	const VkBufferImageCopy					dstCopyRegion			= makeBufferImageCopy(m_parameters.size[0], m_parameters.size[1]);
643 
644 	const VkExtent2D						framebufferSize			(makeExtent2D(m_parameters.size[0], m_parameters.size[1]));
645 	const Move<VkFramebuffer>				framebuffer				(makeFramebuffer(vk, device, *renderPass, 0, DE_NULL, framebufferSize, SINGLE_LAYER));
646 
647 	DE_ASSERT(srcImageSizeInBytes == dstImageSizeInBytes);
648 
649 	// Upload vertex data
650 	deMemcpy(vertexBufferAlloc.getHostPtr(), &vertexArray[0], vertexBufferSizeInBytes);
651 	flushAlloc(vk, device, vertexBufferAlloc);
652 
653 	// Upload source image data
654 	const Allocation& alloc = srcImageBuffer->getAllocation();
655 	deMemcpy(alloc.getHostPtr(), &srcData[0], (size_t)srcImageSizeInBytes);
656 	flushAlloc(vk, device, alloc);
657 
658 	beginCommandBuffer(vk, *cmdBuffer);
659 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
660 
661 	//Copy buffer to image
662 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1u, &srcCopyBufferBarrier, 1u, &srcCopyImageBarrier);
663 	vk.cmdCopyBufferToImage(*cmdBuffer, srcImageBuffer->get(), srcImage->get(), VK_IMAGE_LAYOUT_GENERAL, 1u, &srcCopyRegion);
664 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &srcCopyImageBarrierPost);
665 
666 	// Make source image readable
667 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0u, DE_NULL, 1u, &dstCopyImageBarrier);
668 
669 	beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderSize);
670 	{
671 		DescriptorSetUpdateBuilder()
672 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorSrcImage)
673 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorDstImage)
674 			.update(vk, device);
675 
676 		vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
677 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &vertexBuffer->get(), vertexBufferOffset);
678 		vk.cmdDraw(*cmdBuffer, vertexCount, 1, 0, 0);
679 	}
680 	endRenderPass(vk, *cmdBuffer);
681 
682 	const VkImageMemoryBarrier prepareForTransferBarrier = makeImageMemoryBarrier(
683 		VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
684 		VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
685 		dstImage->get(), subresourceRange);
686 
687 	const VkBufferMemoryBarrier copyBarrier = makeBufferMemoryBarrier(
688 		VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT,
689 		dstImageBuffer->get(), 0ull, dstImageSizeInBytes);
690 
691 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &prepareForTransferBarrier);
692 	vk.cmdCopyImageToBuffer(*cmdBuffer, dstImage->get(), VK_IMAGE_LAYOUT_GENERAL, dstImageBuffer->get(), 1u, &dstCopyRegion);
693 	vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &copyBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
694 
695 	endCommandBuffer(vk, *cmdBuffer);
696 
697 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
698 
699 	const Allocation& dstImageBufferAlloc = dstImageBuffer->getAllocation();
700 	invalidateAlloc(vk, device, dstImageBufferAlloc);
701 	dstData.resize((size_t)dstImageSizeInBytes);
702 	deMemcpy(&dstData[0], dstImageBufferAlloc.getHostPtr(), (size_t)dstImageSizeInBytes);
703 
704 	outputImage = dstImage;
705 }
706 
707 class ImageTranscodingCase : public TestCase
708 {
709 public:
710 							ImageTranscodingCase		(TestContext&				testCtx,
711 														 const std::string&			name,
712 														 const std::string&			desc,
713 														 const TestParameters&		parameters);
714 	void					initPrograms				(SourceCollections&			programCollection) const;
715 	TestInstance*			createInstance				(Context&					context) const;
716 	bool					isFormatUsageFlagSupported	(Context&					context,
717 														 const VkFormat				format,
718 														 VkImageUsageFlags			formatUsageFlags) const;
719 
720 protected:
721 	const TestParameters	m_parameters;
722 };
723 
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)724 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
725 	: TestCase				(testCtx, name, desc)
726 	, m_parameters			(parameters)
727 {
728 }
729 
initPrograms(vk::SourceCollections & programCollection) const730 void ImageTranscodingCase::initPrograms (vk::SourceCollections&	programCollection) const
731 {
732 	DE_ASSERT(m_parameters.size.x() > 0);
733 	DE_ASSERT(m_parameters.size.y() > 0);
734 
735 	ImageType	imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
736 
737 	// Vertex shader
738 	{
739 		std::ostringstream src;
740 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
741 			<< "layout(location = 0) in vec4 v_in_position;\n"
742 			<< "\n"
743 			<< "void main (void)\n"
744 			<< "{\n"
745 			<< "    gl_Position = v_in_position;\n"
746 			<< "}\n";
747 
748 		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
749 	}
750 
751 	// Fragment shader
752 	{
753 		switch(m_parameters.operation)
754 		{
755 			case OPERATION_ATTACHMENT_READ:
756 			case OPERATION_ATTACHMENT_WRITE:
757 			{
758 				std::ostringstream	src;
759 
760 				const std::string	dstTypeStr	= getGlslAttachmentType(m_parameters.featuredFormat);
761 				const std::string	srcTypeStr	= getGlslInputAttachmentType(m_parameters.featuredFormat);
762 
763 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
764 					<< "precision highp int;\n"
765 					<< "precision highp float;\n"
766 					<< "\n"
767 					<< "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
768 					<< "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
769 					<< "\n"
770 					<< "void main (void)\n"
771 					<< "{\n"
772 					<< "    o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
773 					<< "}\n";
774 
775 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
776 
777 				break;
778 			}
779 
780 			case OPERATION_TEXTURE_READ:
781 			case OPERATION_TEXTURE_WRITE:
782 			{
783 				std::ostringstream	src;
784 
785 				const std::string	srcSamplerTypeStr		= getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
786 				const std::string	dstImageTypeStr			= getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
787 				const std::string	dstFormatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
788 
789 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
790 					<< "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
791 					<< "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
792 					<< "\n"
793 					<< "void main (void)\n"
794 					<< "{\n"
795 					<< "    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
796 					<< "    const ivec2 pixels_resolution = ivec2(textureSize(u_imageIn, 0)) - ivec2(1,1);\n"
797 					<< "    const vec2 in_pos = vec2(out_pos) / vec2(pixels_resolution);\n"
798 					<< "    imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
799 					<< "}\n";
800 
801 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
802 
803 				break;
804 			}
805 
806 			default:
807 				DE_ASSERT(false);
808 		}
809 	}
810 }
811 
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const812 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
813 {
814 	const VkPhysicalDevice		physicalDevice			= context.getPhysicalDevice();
815 	const InstanceInterface&	vk						= context.getInstanceInterface();
816 	VkImageFormatProperties		imageFormatProperties;
817 	const VkResult				queryResult				= vk.getPhysicalDeviceImageFormatProperties(
818 															physicalDevice,
819 															format,
820 															mapImageType(m_parameters.imageType),
821 															VK_IMAGE_TILING_OPTIMAL,
822 															formatUsageFlags,
823 															VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,
824 															&imageFormatProperties);
825 
826 	return (queryResult == VK_SUCCESS);
827 }
828 
createInstance(Context & context) const829 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
830 {
831 	VkFormat					featuredFormat		= m_parameters.featuredFormat;
832 	VkFormat					featurelessFormat	= VK_FORMAT_UNDEFINED;
833 	bool						differenceFound		= false;
834 
835 	DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
836 
837 	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_KHR_maintenance2"))
838 		TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance2 not supported");
839 
840 	if (!isFormatUsageFlagSupported(context, featuredFormat, m_parameters.testedImageUsageFeature))
841 		TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
842 
843 	if (!isFormatUsageFlagSupported(context, featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
844 		TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
845 
846 	for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
847 	{
848 		featurelessFormat = m_parameters.compatibleFormats[i];
849 
850 		if (isSupportedByFramework(featurelessFormat)
851 			&& !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
852 			&& isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
853 			)
854 		{
855 			differenceFound = true;
856 
857 			break;
858 		}
859 	}
860 
861 	if (differenceFound)
862 	{
863 		TestParameters	calculatedParameters	=
864 		{
865 			m_parameters.operation,					// Operation				operation
866 			m_parameters.size,						// UVec3					size
867 			m_parameters.imageType,					// ImageType				imageType
868 			m_parameters.testedImageUsageFeature,	// VkImageUsageFlagBits		testedImageUsageFeature
869 			m_parameters.featuredFormat,			// VkFormat					featuredFormat
870 			featurelessFormat,						// VkFormat					featurelessFormat
871 			m_parameters.testedImageUsage,			// VkImageUsageFlags		testedImageUsage
872 			m_parameters.pairedImageUsage,			// VkImageUsageFlags		pairedImageUsage
873 			DE_NULL,								// const VkFormat*			compatibleFormats
874 		};
875 
876 		switch (m_parameters.operation)
877 		{
878 			case OPERATION_ATTACHMENT_READ:
879 			case OPERATION_ATTACHMENT_WRITE:
880 				return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
881 
882 			case OPERATION_TEXTURE_READ:
883 			case OPERATION_TEXTURE_WRITE:
884 				return new GraphicsTextureTestInstance(context, calculatedParameters);
885 
886 			default:
887 				TCU_THROW(InternalError, "Impossible");
888 		}
889 	}
890 	else
891 		TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
892 }
893 
894 } // anonymous ns
895 
896 static const VkFormat	compatibleFormatList8Bit[]		=
897 {
898 	VK_FORMAT_R4G4_UNORM_PACK8,
899 	VK_FORMAT_R8_UNORM,
900 	VK_FORMAT_R8_SNORM,
901 	VK_FORMAT_R8_USCALED,
902 	VK_FORMAT_R8_SSCALED,
903 	VK_FORMAT_R8_UINT,
904 	VK_FORMAT_R8_SINT,
905 	VK_FORMAT_R8_SRGB,
906 
907 	VK_FORMAT_UNDEFINED
908 };
909 
910 static const VkFormat	compatibleFormatList16Bit[]		=
911 {
912 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
913 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
914 	VK_FORMAT_R5G6B5_UNORM_PACK16,
915 	VK_FORMAT_B5G6R5_UNORM_PACK16,
916 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
917 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
918 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
919 	VK_FORMAT_R8G8_UNORM,
920 	VK_FORMAT_R8G8_SNORM,
921 	VK_FORMAT_R8G8_USCALED,
922 	VK_FORMAT_R8G8_SSCALED,
923 	VK_FORMAT_R8G8_UINT,
924 	VK_FORMAT_R8G8_SINT,
925 	VK_FORMAT_R8G8_SRGB,
926 	VK_FORMAT_R16_UNORM,
927 	VK_FORMAT_R16_SNORM,
928 	VK_FORMAT_R16_USCALED,
929 	VK_FORMAT_R16_SSCALED,
930 	VK_FORMAT_R16_UINT,
931 	VK_FORMAT_R16_SINT,
932 	VK_FORMAT_R16_SFLOAT,
933 
934 	VK_FORMAT_UNDEFINED
935 };
936 
937 static const VkFormat	compatibleFormatList24Bit[]		=
938 {
939 	VK_FORMAT_R8G8B8_UNORM,
940 	VK_FORMAT_R8G8B8_SNORM,
941 	VK_FORMAT_R8G8B8_USCALED,
942 	VK_FORMAT_R8G8B8_SSCALED,
943 	VK_FORMAT_R8G8B8_UINT,
944 	VK_FORMAT_R8G8B8_SINT,
945 	VK_FORMAT_R8G8B8_SRGB,
946 	VK_FORMAT_B8G8R8_UNORM,
947 	VK_FORMAT_B8G8R8_SNORM,
948 	VK_FORMAT_B8G8R8_USCALED,
949 	VK_FORMAT_B8G8R8_SSCALED,
950 	VK_FORMAT_B8G8R8_UINT,
951 	VK_FORMAT_B8G8R8_SINT,
952 	VK_FORMAT_B8G8R8_SRGB,
953 
954 	VK_FORMAT_UNDEFINED
955 };
956 
957 static const VkFormat	compatibleFormatList32Bit[]		=
958 {
959 	VK_FORMAT_R8G8B8A8_UNORM,
960 	VK_FORMAT_R8G8B8A8_SNORM,
961 	VK_FORMAT_R8G8B8A8_USCALED,
962 	VK_FORMAT_R8G8B8A8_SSCALED,
963 	VK_FORMAT_R8G8B8A8_UINT,
964 	VK_FORMAT_R8G8B8A8_SINT,
965 	VK_FORMAT_R8G8B8A8_SRGB,
966 	VK_FORMAT_B8G8R8A8_UNORM,
967 	VK_FORMAT_B8G8R8A8_SNORM,
968 	VK_FORMAT_B8G8R8A8_USCALED,
969 	VK_FORMAT_B8G8R8A8_SSCALED,
970 	VK_FORMAT_B8G8R8A8_UINT,
971 	VK_FORMAT_B8G8R8A8_SINT,
972 	VK_FORMAT_B8G8R8A8_SRGB,
973 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
974 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
975 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
976 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
977 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
978 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
979 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
980 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
981 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
982 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
983 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
984 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
985 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
986 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
987 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
988 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
989 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
990 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
991 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
992 	VK_FORMAT_R16G16_UNORM,
993 	VK_FORMAT_R16G16_SNORM,
994 	VK_FORMAT_R16G16_USCALED,
995 	VK_FORMAT_R16G16_SSCALED,
996 	VK_FORMAT_R16G16_UINT,
997 	VK_FORMAT_R16G16_SINT,
998 	VK_FORMAT_R16G16_SFLOAT,
999 	VK_FORMAT_R32_UINT,
1000 	VK_FORMAT_R32_SINT,
1001 	VK_FORMAT_R32_SFLOAT,
1002 
1003 	VK_FORMAT_UNDEFINED
1004 };
1005 
1006 static const VkFormat	compatibleFormatList48Bit[]		=
1007 {
1008 	VK_FORMAT_R16G16B16_UNORM,
1009 	VK_FORMAT_R16G16B16_SNORM,
1010 	VK_FORMAT_R16G16B16_USCALED,
1011 	VK_FORMAT_R16G16B16_SSCALED,
1012 	VK_FORMAT_R16G16B16_UINT,
1013 	VK_FORMAT_R16G16B16_SINT,
1014 	VK_FORMAT_R16G16B16_SFLOAT,
1015 
1016 	VK_FORMAT_UNDEFINED
1017 };
1018 
1019 static const VkFormat	compatibleFormatList64Bit[]		=
1020 {
1021 	VK_FORMAT_R16G16B16A16_UNORM,
1022 	VK_FORMAT_R16G16B16A16_SNORM,
1023 	VK_FORMAT_R16G16B16A16_USCALED,
1024 	VK_FORMAT_R16G16B16A16_SSCALED,
1025 	VK_FORMAT_R16G16B16A16_UINT,
1026 	VK_FORMAT_R16G16B16A16_SINT,
1027 	VK_FORMAT_R16G16B16A16_SFLOAT,
1028 	VK_FORMAT_R32G32_UINT,
1029 	VK_FORMAT_R32G32_SINT,
1030 	VK_FORMAT_R32G32_SFLOAT,
1031 	VK_FORMAT_R64_UINT,
1032 	VK_FORMAT_R64_SINT,
1033 	VK_FORMAT_R64_SFLOAT,
1034 
1035 	VK_FORMAT_UNDEFINED
1036 };
1037 
1038 static const VkFormat	compatibleFormatList96Bit[]		=
1039 {
1040 	VK_FORMAT_R32G32B32_UINT,
1041 	VK_FORMAT_R32G32B32_SINT,
1042 	VK_FORMAT_R32G32B32_SFLOAT,
1043 
1044 	VK_FORMAT_UNDEFINED
1045 };
1046 
1047 static const VkFormat	compatibleFormatList128Bit[]	=
1048 {
1049 	VK_FORMAT_R32G32B32A32_UINT,
1050 	VK_FORMAT_R32G32B32A32_SINT,
1051 	VK_FORMAT_R32G32B32A32_SFLOAT,
1052 	VK_FORMAT_R64G64_UINT,
1053 	VK_FORMAT_R64G64_SINT,
1054 	VK_FORMAT_R64G64_SFLOAT,
1055 
1056 	VK_FORMAT_UNDEFINED
1057 };
1058 
1059 const VkFormat	compatibleFormatList192Bit[]	=
1060 {
1061 	VK_FORMAT_R64G64B64_UINT,
1062 	VK_FORMAT_R64G64B64_SINT,
1063 	VK_FORMAT_R64G64B64_SFLOAT,
1064 
1065 	VK_FORMAT_UNDEFINED
1066 };
1067 
1068 static const VkFormat	compatibleFormatList256Bit[]	=
1069 {
1070 	VK_FORMAT_R64G64B64A64_UINT,
1071 	VK_FORMAT_R64G64B64A64_SINT,
1072 	VK_FORMAT_R64G64B64A64_SFLOAT,
1073 
1074 	VK_FORMAT_UNDEFINED
1075 };
1076 
1077 static const VkFormat*	compatibleFormatsList[]	=
1078 {
1079 	compatibleFormatList8Bit,
1080 	compatibleFormatList16Bit,
1081 	compatibleFormatList24Bit,
1082 	compatibleFormatList32Bit,
1083 	compatibleFormatList48Bit,
1084 	compatibleFormatList64Bit,
1085 	compatibleFormatList96Bit,
1086 	compatibleFormatList128Bit,
1087 	compatibleFormatList192Bit,
1088 	compatibleFormatList256Bit,
1089 };
1090 
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1091 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1092 {
1093 	const std::string			operationName[OPERATION_LAST]			=
1094 	{
1095 		"attachment_read",
1096 		"attachment_write",
1097 		"texture_read",
1098 		"texture_write",
1099 	};
1100 	const VkImageUsageFlagBits	testedImageUsageFlags[OPERATION_LAST]	=
1101 	{
1102 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1103 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1104 		VK_IMAGE_USAGE_SAMPLED_BIT,
1105 		VK_IMAGE_USAGE_STORAGE_BIT,
1106 	};
1107 	const VkImageUsageFlagBits	pairedImageUsageFlags[OPERATION_LAST]	=
1108 	{
1109 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1110 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1111 		VK_IMAGE_USAGE_STORAGE_BIT,
1112 		VK_IMAGE_USAGE_SAMPLED_BIT,
1113 	};
1114 	VkImageUsageFlags			baseFlagsAddOn							= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1115 
1116 	MovePtr<tcu::TestCaseGroup>	imageTranscodingTests	(new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1117 
1118 	for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1119 	{
1120 		MovePtr<tcu::TestCaseGroup>	imageOperationGroup	(new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1121 
1122 		for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1123 		{
1124 			for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1125 			{
1126 				const VkFormat	featuredFormat		= compatibleFormatsList[groupNdx][featuredFormatNdx];
1127 				const VkFormat	featurelessFormat	= VK_FORMAT_UNDEFINED;									// Lookup process is in createInstance()
1128 
1129 				if (!isSupportedByFramework(featuredFormat))
1130 					continue;
1131 
1132 				// Cannot handle SRGB in shader layout classifier
1133 				if (isSrgbFormat(featuredFormat))
1134 					continue;
1135 
1136 				// Cannot handle packed in shader layout classifier
1137 				if (isPackedType(featuredFormat))
1138 					continue;
1139 
1140 				// Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1141 				if (isComponentSwizzled(featuredFormat))
1142 					continue;
1143 
1144 				// Cannot handle three-component images in shader layout classifier
1145 				if (getNumUsedChannels(featuredFormat) == 3)
1146 					continue;
1147 
1148 				const std::string		testName	= getFormatShortString(featuredFormat);
1149 				const TestParameters	parameters	=
1150 				{
1151 					static_cast<Operation>(operationNdx),					// Operation				operation
1152 					UVec3(16u, 16u, 1u),									// UVec3					size
1153 					IMAGE_TYPE_2D,											// ImageType				imageType
1154 					testedImageUsageFlags[operationNdx],					// VkImageUsageFlagBits		testedImageUsageFeature
1155 					featuredFormat,											// VkFormat					featuredFormat
1156 					featurelessFormat,										// VkFormat					featurelessFormat
1157 					baseFlagsAddOn | testedImageUsageFlags[operationNdx],	// VkImageUsageFlags		testedImageUsage
1158 					baseFlagsAddOn | pairedImageUsageFlags[operationNdx],	// VkImageUsageFlags		pairedImageUsage
1159 					compatibleFormatsList[groupNdx]							// const VkFormat*			compatibleFormats
1160 				};
1161 
1162 				imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1163 			}
1164 		}
1165 
1166 		imageTranscodingTests->addChild(imageOperationGroup.release());
1167 	}
1168 
1169 	return imageTranscodingTests.release();
1170 }
1171 
1172 } // image
1173 } // vkt
1174