• 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 "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 ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
835 		TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
836 
837 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
838 		TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
839 
840 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
841 		TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
842 }
843 
createInstance(Context & context) const844 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
845 {
846 	VkFormat					featurelessFormat	= VK_FORMAT_UNDEFINED;
847 	bool						differenceFound		= false;
848 
849 	DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
850 
851 	for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
852 	{
853 		featurelessFormat = m_parameters.compatibleFormats[i];
854 
855 		if (isSupportedByFramework(featurelessFormat)
856 			&& !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
857 			&& isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
858 			)
859 		{
860 			differenceFound = true;
861 
862 			break;
863 		}
864 	}
865 
866 	if (differenceFound)
867 	{
868 		if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
869 			!context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
870 		{
871 			tcu::TextureFormat	textureImageFormat	= vk::mapVkFormat(m_parameters.featuredFormat);
872 			tcu::TextureFormat	textureViewFormat	= vk::mapVkFormat(featurelessFormat);
873 
874 			if (tcu::getTextureFormatBitDepth(textureImageFormat) != tcu::getTextureFormatBitDepth(textureViewFormat))
875 				TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Format must not contain a different number of bits in each component, than the format of the VkImage");
876 		}
877 
878 		TestParameters	calculatedParameters	=
879 		{
880 			m_parameters.operation,					// Operation				operation
881 			m_parameters.size,						// UVec3					size
882 			m_parameters.imageType,					// ImageType				imageType
883 			m_parameters.testedImageUsageFeature,	// VkImageUsageFlagBits		testedImageUsageFeature
884 			m_parameters.featuredFormat,			// VkFormat					featuredFormat
885 			featurelessFormat,						// VkFormat					featurelessFormat
886 			m_parameters.testedImageUsage,			// VkImageUsageFlags		testedImageUsage
887 			m_parameters.pairedImageUsage,			// VkImageUsageFlags		pairedImageUsage
888 			DE_NULL,								// const VkFormat*			compatibleFormats
889 		};
890 
891 		switch (m_parameters.operation)
892 		{
893 			case OPERATION_ATTACHMENT_READ:
894 			case OPERATION_ATTACHMENT_WRITE:
895 				return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
896 
897 			case OPERATION_TEXTURE_READ:
898 			case OPERATION_TEXTURE_WRITE:
899 				return new GraphicsTextureTestInstance(context, calculatedParameters);
900 
901 			default:
902 				TCU_THROW(InternalError, "Impossible");
903 		}
904 	}
905 	else
906 		TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
907 }
908 
909 } // anonymous ns
910 
911 static const VkFormat	compatibleFormatList8Bit[]		=
912 {
913 	VK_FORMAT_R4G4_UNORM_PACK8,
914 	VK_FORMAT_R8_UNORM,
915 	VK_FORMAT_R8_SNORM,
916 	VK_FORMAT_R8_USCALED,
917 	VK_FORMAT_R8_SSCALED,
918 	VK_FORMAT_R8_UINT,
919 	VK_FORMAT_R8_SINT,
920 	VK_FORMAT_R8_SRGB,
921 
922 	VK_FORMAT_UNDEFINED
923 };
924 
925 static const VkFormat	compatibleFormatList16Bit[]		=
926 {
927 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
928 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
929 	VK_FORMAT_R5G6B5_UNORM_PACK16,
930 	VK_FORMAT_B5G6R5_UNORM_PACK16,
931 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
932 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
933 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
934 	VK_FORMAT_R8G8_UNORM,
935 	VK_FORMAT_R8G8_SNORM,
936 	VK_FORMAT_R8G8_USCALED,
937 	VK_FORMAT_R8G8_SSCALED,
938 	VK_FORMAT_R8G8_UINT,
939 	VK_FORMAT_R8G8_SINT,
940 	VK_FORMAT_R8G8_SRGB,
941 	VK_FORMAT_R16_UNORM,
942 	VK_FORMAT_R16_SNORM,
943 	VK_FORMAT_R16_USCALED,
944 	VK_FORMAT_R16_SSCALED,
945 	VK_FORMAT_R16_UINT,
946 	VK_FORMAT_R16_SINT,
947 	VK_FORMAT_R16_SFLOAT,
948 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
949 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
950 
951 	VK_FORMAT_UNDEFINED
952 };
953 
954 static const VkFormat	compatibleFormatList24Bit[]		=
955 {
956 	VK_FORMAT_R8G8B8_UNORM,
957 	VK_FORMAT_R8G8B8_SNORM,
958 	VK_FORMAT_R8G8B8_USCALED,
959 	VK_FORMAT_R8G8B8_SSCALED,
960 	VK_FORMAT_R8G8B8_UINT,
961 	VK_FORMAT_R8G8B8_SINT,
962 	VK_FORMAT_R8G8B8_SRGB,
963 	VK_FORMAT_B8G8R8_UNORM,
964 	VK_FORMAT_B8G8R8_SNORM,
965 	VK_FORMAT_B8G8R8_USCALED,
966 	VK_FORMAT_B8G8R8_SSCALED,
967 	VK_FORMAT_B8G8R8_UINT,
968 	VK_FORMAT_B8G8R8_SINT,
969 	VK_FORMAT_B8G8R8_SRGB,
970 
971 	VK_FORMAT_UNDEFINED
972 };
973 
974 static const VkFormat	compatibleFormatList32Bit[]		=
975 {
976 	VK_FORMAT_R8G8B8A8_UNORM,
977 	VK_FORMAT_R8G8B8A8_SNORM,
978 	VK_FORMAT_R8G8B8A8_USCALED,
979 	VK_FORMAT_R8G8B8A8_SSCALED,
980 	VK_FORMAT_R8G8B8A8_UINT,
981 	VK_FORMAT_R8G8B8A8_SINT,
982 	VK_FORMAT_R8G8B8A8_SRGB,
983 	VK_FORMAT_B8G8R8A8_UNORM,
984 	VK_FORMAT_B8G8R8A8_SNORM,
985 	VK_FORMAT_B8G8R8A8_USCALED,
986 	VK_FORMAT_B8G8R8A8_SSCALED,
987 	VK_FORMAT_B8G8R8A8_UINT,
988 	VK_FORMAT_B8G8R8A8_SINT,
989 	VK_FORMAT_B8G8R8A8_SRGB,
990 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
991 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
992 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
993 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
994 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
995 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
996 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
997 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
998 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
999 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1000 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1001 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
1002 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
1003 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1004 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1005 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1006 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1007 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
1008 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
1009 	VK_FORMAT_R16G16_UNORM,
1010 	VK_FORMAT_R16G16_SNORM,
1011 	VK_FORMAT_R16G16_USCALED,
1012 	VK_FORMAT_R16G16_SSCALED,
1013 	VK_FORMAT_R16G16_UINT,
1014 	VK_FORMAT_R16G16_SINT,
1015 	VK_FORMAT_R16G16_SFLOAT,
1016 	VK_FORMAT_R32_UINT,
1017 	VK_FORMAT_R32_SINT,
1018 	VK_FORMAT_R32_SFLOAT,
1019 
1020 	VK_FORMAT_UNDEFINED
1021 };
1022 
1023 static const VkFormat	compatibleFormatList48Bit[]		=
1024 {
1025 	VK_FORMAT_R16G16B16_UNORM,
1026 	VK_FORMAT_R16G16B16_SNORM,
1027 	VK_FORMAT_R16G16B16_USCALED,
1028 	VK_FORMAT_R16G16B16_SSCALED,
1029 	VK_FORMAT_R16G16B16_UINT,
1030 	VK_FORMAT_R16G16B16_SINT,
1031 	VK_FORMAT_R16G16B16_SFLOAT,
1032 
1033 	VK_FORMAT_UNDEFINED
1034 };
1035 
1036 static const VkFormat	compatibleFormatList64Bit[]		=
1037 {
1038 	VK_FORMAT_R16G16B16A16_UNORM,
1039 	VK_FORMAT_R16G16B16A16_SNORM,
1040 	VK_FORMAT_R16G16B16A16_USCALED,
1041 	VK_FORMAT_R16G16B16A16_SSCALED,
1042 	VK_FORMAT_R16G16B16A16_UINT,
1043 	VK_FORMAT_R16G16B16A16_SINT,
1044 	VK_FORMAT_R16G16B16A16_SFLOAT,
1045 	VK_FORMAT_R32G32_UINT,
1046 	VK_FORMAT_R32G32_SINT,
1047 	VK_FORMAT_R32G32_SFLOAT,
1048 	VK_FORMAT_R64_UINT,
1049 	VK_FORMAT_R64_SINT,
1050 	VK_FORMAT_R64_SFLOAT,
1051 
1052 	VK_FORMAT_UNDEFINED
1053 };
1054 
1055 static const VkFormat	compatibleFormatList96Bit[]		=
1056 {
1057 	VK_FORMAT_R32G32B32_UINT,
1058 	VK_FORMAT_R32G32B32_SINT,
1059 	VK_FORMAT_R32G32B32_SFLOAT,
1060 
1061 	VK_FORMAT_UNDEFINED
1062 };
1063 
1064 static const VkFormat	compatibleFormatList128Bit[]	=
1065 {
1066 	VK_FORMAT_R32G32B32A32_UINT,
1067 	VK_FORMAT_R32G32B32A32_SINT,
1068 	VK_FORMAT_R32G32B32A32_SFLOAT,
1069 	VK_FORMAT_R64G64_UINT,
1070 	VK_FORMAT_R64G64_SINT,
1071 	VK_FORMAT_R64G64_SFLOAT,
1072 
1073 	VK_FORMAT_UNDEFINED
1074 };
1075 
1076 const VkFormat	compatibleFormatList192Bit[]	=
1077 {
1078 	VK_FORMAT_R64G64B64_UINT,
1079 	VK_FORMAT_R64G64B64_SINT,
1080 	VK_FORMAT_R64G64B64_SFLOAT,
1081 
1082 	VK_FORMAT_UNDEFINED
1083 };
1084 
1085 static const VkFormat	compatibleFormatList256Bit[]	=
1086 {
1087 	VK_FORMAT_R64G64B64A64_UINT,
1088 	VK_FORMAT_R64G64B64A64_SINT,
1089 	VK_FORMAT_R64G64B64A64_SFLOAT,
1090 
1091 	VK_FORMAT_UNDEFINED
1092 };
1093 
1094 static const VkFormat*	compatibleFormatsList[]	=
1095 {
1096 	compatibleFormatList8Bit,
1097 	compatibleFormatList16Bit,
1098 	compatibleFormatList24Bit,
1099 	compatibleFormatList32Bit,
1100 	compatibleFormatList48Bit,
1101 	compatibleFormatList64Bit,
1102 	compatibleFormatList96Bit,
1103 	compatibleFormatList128Bit,
1104 	compatibleFormatList192Bit,
1105 	compatibleFormatList256Bit,
1106 };
1107 
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1108 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1109 {
1110 	const std::string			operationName[OPERATION_LAST]			=
1111 	{
1112 		"attachment_read",
1113 		"attachment_write",
1114 		"texture_read",
1115 		"texture_write",
1116 	};
1117 	const VkImageUsageFlagBits	testedImageUsageFlags[OPERATION_LAST]	=
1118 	{
1119 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1120 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1121 		VK_IMAGE_USAGE_SAMPLED_BIT,
1122 		VK_IMAGE_USAGE_STORAGE_BIT,
1123 	};
1124 	const VkImageUsageFlagBits	pairedImageUsageFlags[OPERATION_LAST]	=
1125 	{
1126 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1127 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1128 		VK_IMAGE_USAGE_STORAGE_BIT,
1129 		VK_IMAGE_USAGE_SAMPLED_BIT,
1130 	};
1131 	VkImageUsageFlags			baseFlagsAddOn							= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1132 
1133 	MovePtr<tcu::TestCaseGroup>	imageTranscodingTests	(new tcu::TestCaseGroup(testCtx, "extended_usage_bit", "Extended usage bit test cases"));
1134 
1135 	for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1136 	{
1137 		MovePtr<tcu::TestCaseGroup>	imageOperationGroup	(new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str(), ""));
1138 
1139 		for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1140 		{
1141 			for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1142 			{
1143 				const VkFormat	featuredFormat		= compatibleFormatsList[groupNdx][featuredFormatNdx];
1144 				const VkFormat	featurelessFormat	= VK_FORMAT_UNDEFINED;									// Lookup process is in createInstance()
1145 
1146 				if (!isSupportedByFramework(featuredFormat))
1147 					continue;
1148 
1149 				// Cannot handle SRGB in shader layout classifier
1150 				if (isSrgbFormat(featuredFormat))
1151 					continue;
1152 
1153 				// Cannot handle packed in shader layout classifier
1154 				if (isPackedType(featuredFormat))
1155 					continue;
1156 
1157 				// Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1158 				if (isComponentSwizzled(featuredFormat))
1159 					continue;
1160 
1161 				// Cannot handle three-component images in shader layout classifier
1162 				if (getNumUsedChannels(featuredFormat) == 3)
1163 					continue;
1164 
1165 				const std::string		testName	= getFormatShortString(featuredFormat);
1166 				const TestParameters	parameters	=
1167 				{
1168 					static_cast<Operation>(operationNdx),					// Operation				operation
1169 					UVec3(16u, 16u, 1u),									// UVec3					size
1170 					IMAGE_TYPE_2D,											// ImageType				imageType
1171 					testedImageUsageFlags[operationNdx],					// VkImageUsageFlagBits		testedImageUsageFeature
1172 					featuredFormat,											// VkFormat					featuredFormat
1173 					featurelessFormat,										// VkFormat					featurelessFormat
1174 					baseFlagsAddOn | testedImageUsageFlags[operationNdx],	// VkImageUsageFlags		testedImageUsage
1175 					baseFlagsAddOn | pairedImageUsageFlags[operationNdx],	// VkImageUsageFlags		pairedImageUsage
1176 					compatibleFormatsList[groupNdx]							// const VkFormat*			compatibleFormats
1177 				};
1178 
1179 				imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, "", parameters));
1180 			}
1181 		}
1182 
1183 		imageTranscodingTests->addChild(imageOperationGroup.release());
1184 	}
1185 
1186 	return imageTranscodingTests.release();
1187 }
1188 
1189 } // image
1190 } // vkt
1191