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