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