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 #include "vkObjUtil.hpp"
43 
44 #include "tcuTextureUtil.hpp"
45 #include "tcuTexture.hpp"
46 #include "tcuCompressedTexture.hpp"
47 #include "tcuVectorType.hpp"
48 #include "tcuResource.hpp"
49 #include "tcuImageIO.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "tcuTestLog.hpp"
52 #include "tcuRGBA.hpp"
53 #include "tcuSurface.hpp"
54 #include "tcuFloat.hpp"
55 
56 #include <vector>
57 #include <iomanip>
58 
59 using namespace vk;
60 namespace vkt
61 {
62 namespace image
63 {
64 namespace
65 {
66 using std::string;
67 using std::vector;
68 using tcu::TestContext;
69 using tcu::TestStatus;
70 using tcu::UVec3;
71 using tcu::IVec3;
72 using tcu::CompressedTexFormat;
73 using tcu::CompressedTexture;
74 using tcu::Resource;
75 using tcu::Archive;
76 using tcu::ConstPixelBufferAccess;
77 using de::MovePtr;
78 using de::SharedPtr;
79 using de::Random;
80 
81 enum Operation
82 {
83 	OPERATION_ATTACHMENT_READ,
84 	OPERATION_ATTACHMENT_WRITE,
85 	OPERATION_TEXTURE_READ,
86 	OPERATION_TEXTURE_WRITE,
87 	OPERATION_LAST
88 };
89 
90 struct TestParameters
91 {
92 	Operation				operation;
93 	UVec3					size;
94 	ImageType				imageType;
95 	VkImageUsageFlagBits	testedImageUsageFeature;
96 	VkFormat				featuredFormat;
97 	VkFormat				featurelessFormat;
98 	VkImageUsageFlags		testedImageUsage;
99 	VkImageUsageFlags		pairedImageUsage;
100 	const VkFormat*			compatibleFormats;
101 };
102 
103 const deUint32 SINGLE_LEVEL = 1u;
104 const deUint32 SINGLE_LAYER = 1u;
105 
106 class BasicTranscodingTestInstance : public TestInstance
107 {
108 public:
109 							BasicTranscodingTestInstance	(Context&				context,
110 															 const TestParameters&	parameters);
111 	virtual TestStatus		iterate							(void) = 0;
112 protected:
113 	void					generateData					(deUint8*				toFill,
114 															 size_t					size,
115 															 const VkFormat			format = VK_FORMAT_UNDEFINED);
116 	const TestParameters	m_parameters;
117 };
118 
BasicTranscodingTestInstance(Context & context,const TestParameters & parameters)119 BasicTranscodingTestInstance::BasicTranscodingTestInstance (Context& context, const TestParameters& parameters)
120 	: TestInstance	(context)
121 	, m_parameters	(parameters)
122 {
123 }
124 
125 // Replace Infs and NaNs with the largest normal value.
126 // Replace denormal numbers with the smallest normal value.
127 // Leave the rest untouched.
128 // T is a tcu::Float specialization.
129 template <class T>
fixFloatIfNeeded(deUint8 * ptr_)130 void fixFloatIfNeeded(deUint8* ptr_)
131 {
132 	T* ptr = reinterpret_cast<T*>(ptr_);
133 	if (ptr->isInf() || ptr->isNaN())
134 		*ptr = T::largestNormal(ptr->sign());
135 	else if (ptr->isDenorm())
136 		*ptr = T::smallestNormal(ptr->sign());
137 }
138 
generateData(deUint8 * toFill,size_t size,const VkFormat format)139 void BasicTranscodingTestInstance::generateData (deUint8* toFill, size_t size, const VkFormat format)
140 {
141 	const deUint8 pattern[] =
142 	{
143 		// 64-bit values
144 		0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22,
145 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
147 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
148 		0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
149 		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
150 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
151 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
152 		0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
153 		0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
154 		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Positive infinity
155 		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Negative infinity
156 		0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
157 		0x7F, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
158 		0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,		// Start of a signalling NaN (NANS)
159 		0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a signalling NaN (NANS)
160 		0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
161 		0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of of a quiet NaN (NANQ)
162 		0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		// Start of a quiet NaN (NANQ)
163 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,		// End of a quiet NaN (NANQ)
164 		// 32-bit values
165 		0x7F, 0x80, 0x00, 0x00,								// Positive infinity
166 		0xFF, 0x80, 0x00, 0x00,								// Negative infinity
167 		0x7F, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
168 		0x7F, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
169 		0xFF, 0x80, 0x00, 0x01,								// Start of a signalling NaN (NANS)
170 		0xFF, 0xBF, 0xFF, 0xFF,								// End of a signalling NaN (NANS)
171 		0x7F, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
172 		0x7F, 0xFF, 0xFF, 0xFF,								// End of of a quiet NaN (NANQ)
173 		0xFF, 0xC0, 0x00, 0x00,								// Start of a quiet NaN (NANQ)
174 		0xFF, 0xFF, 0xFF, 0xFF,								// End of a quiet NaN (NANQ)
175 		0xAA, 0xAA, 0xAA, 0xAA,
176 		0x55, 0x55, 0x55, 0x55,
177 	};
178 
179 	deUint8*	start		= toFill;
180 	size_t		sizeToRnd	= size;
181 
182 	// Pattern part
183 	if (size >= 2 * sizeof(pattern))
184 	{
185 		// Rotated pattern
186 		for (size_t i = 0; i < sizeof(pattern); i++)
187 			start[sizeof(pattern) - i - 1] = pattern[i];
188 
189 		start		+= sizeof(pattern);
190 		sizeToRnd	-= sizeof(pattern);
191 
192 		// Direct pattern
193 		deMemcpy(start, pattern, sizeof(pattern));
194 
195 		start		+= sizeof(pattern);
196 		sizeToRnd	-= sizeof(pattern);
197 	}
198 
199 	// Random part
200 	{
201 		DE_ASSERT(sizeToRnd % sizeof(deUint32) == 0);
202 
203 		deUint32*	start32		= reinterpret_cast<deUint32*>(start);
204 		size_t		sizeToRnd32	= sizeToRnd / sizeof(deUint32);
205 		Random		rnd			(static_cast<deUint32>(format));
206 
207 		for (size_t i = 0; i < sizeToRnd32; i++)
208 			start32[i] = rnd.getUint32();
209 	}
210 
211 	{
212 		// Remove certain values that may not be preserved based on the uncompressed view format
213 		if (isSnormFormat(m_parameters.featuredFormat))
214 		{
215 			tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
216 
217 			if (textureFormat.type == tcu::TextureFormat::SNORM_INT8)
218 			{
219 				for (size_t i = 0; i < size; i++)
220 				{
221 					// SNORM fix: due to write operation in SNORM format
222 					// replaces 0x80 to 0x81, remove these values from test
223 					if (toFill[i] == 0x80)
224 						toFill[i] = 0x81;
225 				}
226 			}
227 			else
228 			{
229 				for (size_t i = 0; i < size; i += 2)
230 				{
231 					// SNORM fix: due to write operation in SNORM format
232 					// replaces 0x00 0x80 to 0x01 0x80
233 					if (toFill[i] == 0x00 && toFill[i+1] == 0x80)
234 						toFill[i+1] = 0x81;
235 				}
236 			}
237 		}
238 		else if (isFloatFormat(m_parameters.featuredFormat))
239 		{
240 			tcu::TextureFormat textureFormat = mapVkFormat(m_parameters.featuredFormat);
241 
242 			if (textureFormat.type == tcu::TextureFormat::HALF_FLOAT)
243 			{
244 				for (size_t i = 0; i < size; i += 2)
245 					fixFloatIfNeeded<tcu::Float16>(toFill + i);
246 			}
247 			else if (textureFormat.type == tcu::TextureFormat::FLOAT)
248 			{
249 				for (size_t i = 0; i < size; i += 4)
250 					fixFloatIfNeeded<tcu::Float16>(toFill + i);
251 
252 				for (size_t i = 0; i < size; i += 4)
253 					fixFloatIfNeeded<tcu::Float32>(toFill + i);
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				(vkt::image::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.width, renderSize.height, 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.width, framebufferSize.height, 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 	virtual void			checkSupport				(Context&					context) const;
717 	bool					isFormatUsageFlagSupported	(Context&					context,
718 														 const VkFormat				format,
719 														 VkImageUsageFlags			formatUsageFlags) const;
720 
721 protected:
722 	const TestParameters	m_parameters;
723 };
724 
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const std::string & desc,const TestParameters & parameters)725 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const std::string& desc, const TestParameters& parameters)
726 	: TestCase				(testCtx, name, desc)
727 	, m_parameters			(parameters)
728 {
729 }
730 
initPrograms(vk::SourceCollections & programCollection) const731 void ImageTranscodingCase::initPrograms (vk::SourceCollections&	programCollection) const
732 {
733 	DE_ASSERT(m_parameters.size.x() > 0);
734 	DE_ASSERT(m_parameters.size.y() > 0);
735 
736 	ImageType	imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
737 
738 	// Vertex shader
739 	{
740 		std::ostringstream src;
741 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
742 			<< "layout(location = 0) in vec4 v_in_position;\n"
743 			<< "\n"
744 			<< "void main (void)\n"
745 			<< "{\n"
746 			<< "    gl_Position = v_in_position;\n"
747 			<< "}\n";
748 
749 		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
750 	}
751 
752 	// Fragment shader
753 	{
754 		switch(m_parameters.operation)
755 		{
756 			case OPERATION_ATTACHMENT_READ:
757 			case OPERATION_ATTACHMENT_WRITE:
758 			{
759 				std::ostringstream	src;
760 
761 				const std::string	dstTypeStr	= getGlslAttachmentType(m_parameters.featuredFormat);
762 				const std::string	srcTypeStr	= getGlslInputAttachmentType(m_parameters.featuredFormat);
763 
764 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
765 					<< "precision highp int;\n"
766 					<< "precision highp float;\n"
767 					<< "\n"
768 					<< "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
769 					<< "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
770 					<< "\n"
771 					<< "void main (void)\n"
772 					<< "{\n"
773 					<< "    o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
774 					<< "}\n";
775 
776 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
777 
778 				break;
779 			}
780 
781 			case OPERATION_TEXTURE_READ:
782 			case OPERATION_TEXTURE_WRITE:
783 			{
784 				std::ostringstream	src;
785 
786 				const std::string	srcSamplerTypeStr		= getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
787 				const std::string	dstImageTypeStr			= getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
788 				const std::string	dstFormatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
789 
790 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
791 					<< "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
792 					<< "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
793 					<< "\n"
794 					<< "void main (void)\n"
795 					<< "{\n"
796 					<< "    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
797 					<< "    const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
798 					<< "    const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n"
799 					<< "    imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
800 					<< "}\n";
801 
802 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
803 
804 				break;
805 			}
806 
807 			default:
808 				DE_ASSERT(false);
809 		}
810 	}
811 }
812 
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const813 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
814 {
815 	const VkPhysicalDevice		physicalDevice			= context.getPhysicalDevice();
816 	const InstanceInterface&	vk						= context.getInstanceInterface();
817 	VkImageFormatProperties		imageFormatProperties;
818 	const VkResult				queryResult				= vk.getPhysicalDeviceImageFormatProperties(
819 															physicalDevice,
820 															format,
821 															mapImageType(m_parameters.imageType),
822 															VK_IMAGE_TILING_OPTIMAL,
823 															formatUsageFlags,
824 															VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR,
825 															&imageFormatProperties);
826 
827 	return (queryResult == VK_SUCCESS);
828 }
829 
checkSupport(Context & context) const830 void ImageTranscodingCase::checkSupport (Context& context) const
831 {
832 	context.requireDeviceFunctionality("VK_KHR_maintenance2");
833 
834 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
835 		TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
836 
837 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
838 		TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
839 }
840 
createInstance(Context & context) const841 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
842 {
843 	VkFormat					featurelessFormat	= VK_FORMAT_UNDEFINED;
844 	bool						differenceFound		= false;
845 
846 	DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
847 
848 	for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
849 	{
850 		featurelessFormat = m_parameters.compatibleFormats[i];
851 
852 		if (isSupportedByFramework(featurelessFormat)
853 			&& !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
854 			&& isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
855 			)
856 		{
857 			differenceFound = true;
858 
859 			break;
860 		}
861 	}
862 
863 	if (differenceFound)
864 	{
865 		TestParameters	calculatedParameters	=
866 		{
867 			m_parameters.operation,					// Operation				operation
868 			m_parameters.size,						// UVec3					size
869 			m_parameters.imageType,					// ImageType				imageType
870 			m_parameters.testedImageUsageFeature,	// VkImageUsageFlagBits		testedImageUsageFeature
871 			m_parameters.featuredFormat,			// VkFormat					featuredFormat
872 			featurelessFormat,						// VkFormat					featurelessFormat
873 			m_parameters.testedImageUsage,			// VkImageUsageFlags		testedImageUsage
874 			m_parameters.pairedImageUsage,			// VkImageUsageFlags		pairedImageUsage
875 			DE_NULL,								// const VkFormat*			compatibleFormats
876 		};
877 
878 		switch (m_parameters.operation)
879 		{
880 			case OPERATION_ATTACHMENT_READ:
881 			case OPERATION_ATTACHMENT_WRITE:
882 				return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
883 
884 			case OPERATION_TEXTURE_READ:
885 			case OPERATION_TEXTURE_WRITE:
886 				return new GraphicsTextureTestInstance(context, calculatedParameters);
887 
888 			default:
889 				TCU_THROW(InternalError, "Impossible");
890 		}
891 	}
892 	else
893 		TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
894 }
895 
896 } // anonymous ns
897 
898 static const VkFormat	compatibleFormatList8Bit[]		=
899 {
900 	VK_FORMAT_R4G4_UNORM_PACK8,
901 	VK_FORMAT_R8_UNORM,
902 	VK_FORMAT_R8_SNORM,
903 	VK_FORMAT_R8_USCALED,
904 	VK_FORMAT_R8_SSCALED,
905 	VK_FORMAT_R8_UINT,
906 	VK_FORMAT_R8_SINT,
907 	VK_FORMAT_R8_SRGB,
908 
909 	VK_FORMAT_UNDEFINED
910 };
911 
912 static const VkFormat	compatibleFormatList16Bit[]		=
913 {
914 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
915 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
916 	VK_FORMAT_R5G6B5_UNORM_PACK16,
917 	VK_FORMAT_B5G6R5_UNORM_PACK16,
918 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
919 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
920 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
921 	VK_FORMAT_R8G8_UNORM,
922 	VK_FORMAT_R8G8_SNORM,
923 	VK_FORMAT_R8G8_USCALED,
924 	VK_FORMAT_R8G8_SSCALED,
925 	VK_FORMAT_R8G8_UINT,
926 	VK_FORMAT_R8G8_SINT,
927 	VK_FORMAT_R8G8_SRGB,
928 	VK_FORMAT_R16_UNORM,
929 	VK_FORMAT_R16_SNORM,
930 	VK_FORMAT_R16_USCALED,
931 	VK_FORMAT_R16_SSCALED,
932 	VK_FORMAT_R16_UINT,
933 	VK_FORMAT_R16_SINT,
934 	VK_FORMAT_R16_SFLOAT,
935 
936 	VK_FORMAT_UNDEFINED
937 };
938 
939 static const VkFormat	compatibleFormatList24Bit[]		=
940 {
941 	VK_FORMAT_R8G8B8_UNORM,
942 	VK_FORMAT_R8G8B8_SNORM,
943 	VK_FORMAT_R8G8B8_USCALED,
944 	VK_FORMAT_R8G8B8_SSCALED,
945 	VK_FORMAT_R8G8B8_UINT,
946 	VK_FORMAT_R8G8B8_SINT,
947 	VK_FORMAT_R8G8B8_SRGB,
948 	VK_FORMAT_B8G8R8_UNORM,
949 	VK_FORMAT_B8G8R8_SNORM,
950 	VK_FORMAT_B8G8R8_USCALED,
951 	VK_FORMAT_B8G8R8_SSCALED,
952 	VK_FORMAT_B8G8R8_UINT,
953 	VK_FORMAT_B8G8R8_SINT,
954 	VK_FORMAT_B8G8R8_SRGB,
955 
956 	VK_FORMAT_UNDEFINED
957 };
958 
959 static const VkFormat	compatibleFormatList32Bit[]		=
960 {
961 	VK_FORMAT_R8G8B8A8_UNORM,
962 	VK_FORMAT_R8G8B8A8_SNORM,
963 	VK_FORMAT_R8G8B8A8_USCALED,
964 	VK_FORMAT_R8G8B8A8_SSCALED,
965 	VK_FORMAT_R8G8B8A8_UINT,
966 	VK_FORMAT_R8G8B8A8_SINT,
967 	VK_FORMAT_R8G8B8A8_SRGB,
968 	VK_FORMAT_B8G8R8A8_UNORM,
969 	VK_FORMAT_B8G8R8A8_SNORM,
970 	VK_FORMAT_B8G8R8A8_USCALED,
971 	VK_FORMAT_B8G8R8A8_SSCALED,
972 	VK_FORMAT_B8G8R8A8_UINT,
973 	VK_FORMAT_B8G8R8A8_SINT,
974 	VK_FORMAT_B8G8R8A8_SRGB,
975 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
976 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
977 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
978 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
979 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
980 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
981 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
982 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
983 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
984 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
985 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
986 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
987 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
988 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
989 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
990 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
991 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
992 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
993 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
994 	VK_FORMAT_R16G16_UNORM,
995 	VK_FORMAT_R16G16_SNORM,
996 	VK_FORMAT_R16G16_USCALED,
997 	VK_FORMAT_R16G16_SSCALED,
998 	VK_FORMAT_R16G16_UINT,
999 	VK_FORMAT_R16G16_SINT,
1000 	VK_FORMAT_R16G16_SFLOAT,
1001 	VK_FORMAT_R32_UINT,
1002 	VK_FORMAT_R32_SINT,
1003 	VK_FORMAT_R32_SFLOAT,
1004 
1005 	VK_FORMAT_UNDEFINED
1006 };
1007 
1008 static const VkFormat	compatibleFormatList48Bit[]		=
1009 {
1010 	VK_FORMAT_R16G16B16_UNORM,
1011 	VK_FORMAT_R16G16B16_SNORM,
1012 	VK_FORMAT_R16G16B16_USCALED,
1013 	VK_FORMAT_R16G16B16_SSCALED,
1014 	VK_FORMAT_R16G16B16_UINT,
1015 	VK_FORMAT_R16G16B16_SINT,
1016 	VK_FORMAT_R16G16B16_SFLOAT,
1017 
1018 	VK_FORMAT_UNDEFINED
1019 };
1020 
1021 static const VkFormat	compatibleFormatList64Bit[]		=
1022 {
1023 	VK_FORMAT_R16G16B16A16_UNORM,
1024 	VK_FORMAT_R16G16B16A16_SNORM,
1025 	VK_FORMAT_R16G16B16A16_USCALED,
1026 	VK_FORMAT_R16G16B16A16_SSCALED,
1027 	VK_FORMAT_R16G16B16A16_UINT,
1028 	VK_FORMAT_R16G16B16A16_SINT,
1029 	VK_FORMAT_R16G16B16A16_SFLOAT,
1030 	VK_FORMAT_R32G32_UINT,
1031 	VK_FORMAT_R32G32_SINT,
1032 	VK_FORMAT_R32G32_SFLOAT,
1033 	VK_FORMAT_R64_UINT,
1034 	VK_FORMAT_R64_SINT,
1035 	VK_FORMAT_R64_SFLOAT,
1036 
1037 	VK_FORMAT_UNDEFINED
1038 };
1039 
1040 static const VkFormat	compatibleFormatList96Bit[]		=
1041 {
1042 	VK_FORMAT_R32G32B32_UINT,
1043 	VK_FORMAT_R32G32B32_SINT,
1044 	VK_FORMAT_R32G32B32_SFLOAT,
1045 
1046 	VK_FORMAT_UNDEFINED
1047 };
1048 
1049 static const VkFormat	compatibleFormatList128Bit[]	=
1050 {
1051 	VK_FORMAT_R32G32B32A32_UINT,
1052 	VK_FORMAT_R32G32B32A32_SINT,
1053 	VK_FORMAT_R32G32B32A32_SFLOAT,
1054 	VK_FORMAT_R64G64_UINT,
1055 	VK_FORMAT_R64G64_SINT,
1056 	VK_FORMAT_R64G64_SFLOAT,
1057 
1058 	VK_FORMAT_UNDEFINED
1059 };
1060 
1061 const VkFormat	compatibleFormatList192Bit[]	=
1062 {
1063 	VK_FORMAT_R64G64B64_UINT,
1064 	VK_FORMAT_R64G64B64_SINT,
1065 	VK_FORMAT_R64G64B64_SFLOAT,
1066 
1067 	VK_FORMAT_UNDEFINED
1068 };
1069 
1070 static const VkFormat	compatibleFormatList256Bit[]	=
1071 {
1072 	VK_FORMAT_R64G64B64A64_UINT,
1073 	VK_FORMAT_R64G64B64A64_SINT,
1074 	VK_FORMAT_R64G64B64A64_SFLOAT,
1075 
1076 	VK_FORMAT_UNDEFINED
1077 };
1078 
1079 static const VkFormat*	compatibleFormatsList[]	=
1080 {
1081 	compatibleFormatList8Bit,
1082 	compatibleFormatList16Bit,
1083 	compatibleFormatList24Bit,
1084 	compatibleFormatList32Bit,
1085 	compatibleFormatList48Bit,
1086 	compatibleFormatList64Bit,
1087 	compatibleFormatList96Bit,
1088 	compatibleFormatList128Bit,
1089 	compatibleFormatList192Bit,
1090 	compatibleFormatList256Bit,
1091 };
1092 
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1093 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1094 {
1095 	const std::string			operationName[OPERATION_LAST]			=
1096 	{
1097 		"attachment_read",
1098 		"attachment_write",
1099 		"texture_read",
1100 		"texture_write",
1101 	};
1102 	const VkImageUsageFlagBits	testedImageUsageFlags[OPERATION_LAST]	=
1103 	{
1104 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1105 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1106 		VK_IMAGE_USAGE_SAMPLED_BIT,
1107 		VK_IMAGE_USAGE_STORAGE_BIT,
1108 	};
1109 	const VkImageUsageFlagBits	pairedImageUsageFlags[OPERATION_LAST]	=
1110 	{
1111 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1112 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1113 		VK_IMAGE_USAGE_STORAGE_BIT,
1114 		VK_IMAGE_USAGE_SAMPLED_BIT,
1115 	};
1116 	VkImageUsageFlags			baseFlagsAddOn							= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1117 
1118 	MovePtr<tcu::TestCaseGroup>	imageTranscodingTests	(new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1119 
1120 	for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1121 	{
1122 		MovePtr<tcu::TestCaseGroup>	imageOperationGroup	(new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1123 
1124 		for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1125 		{
1126 			for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1127 			{
1128 				const VkFormat	featuredFormat		= compatibleFormatsList[groupNdx][featuredFormatNdx];
1129 				const VkFormat	featurelessFormat	= VK_FORMAT_UNDEFINED;									// Lookup process is in createInstance()
1130 
1131 				if (!isSupportedByFramework(featuredFormat))
1132 					continue;
1133 
1134 				// Cannot handle SRGB in shader layout classifier
1135 				if (isSrgbFormat(featuredFormat))
1136 					continue;
1137 
1138 				// Cannot handle packed in shader layout classifier
1139 				if (isPackedType(featuredFormat))
1140 					continue;
1141 
1142 				// Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1143 				if (isComponentSwizzled(featuredFormat))
1144 					continue;
1145 
1146 				// Cannot handle three-component images in shader layout classifier
1147 				if (getNumUsedChannels(featuredFormat) == 3)
1148 					continue;
1149 
1150 				const std::string		testName	= getFormatShortString(featuredFormat);
1151 				const TestParameters	parameters	=
1152 				{
1153 					static_cast<Operation>(operationNdx),					// Operation				operation
1154 					UVec3(16u, 16u, 1u),									// UVec3					size
1155 					IMAGE_TYPE_2D,											// ImageType				imageType
1156 					testedImageUsageFlags[operationNdx],					// VkImageUsageFlagBits		testedImageUsageFeature
1157 					featuredFormat,											// VkFormat					featuredFormat
1158 					featurelessFormat,										// VkFormat					featurelessFormat
1159 					baseFlagsAddOn | testedImageUsageFlags[operationNdx],	// VkImageUsageFlags		testedImageUsage
1160 					baseFlagsAddOn | pairedImageUsageFlags[operationNdx],	// VkImageUsageFlags		pairedImageUsage
1161 					compatibleFormatsList[groupNdx]							// const VkFormat*			compatibleFormats
1162 				};
1163 
1164 				imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1165 			}
1166 		}
1167 
1168 		imageTranscodingTests->addChild(imageOperationGroup.release());
1169 	}
1170 
1171 	return imageTranscodingTests.release();
1172 }
1173 
1174 } // image
1175 } // vkt
1176