• 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 TestParameters&		parameters);
723 	void					initPrograms				(SourceCollections&			programCollection) const;
724 	TestInstance*			createInstance				(Context&					context) const;
725 	virtual void			checkSupport				(Context&					context) const;
726 	bool					isFormatUsageFlagSupported	(Context&					context,
727 														 const VkFormat				format,
728 														 VkImageUsageFlags			formatUsageFlags) const;
729 
730 protected:
731 	const TestParameters	m_parameters;
732 };
733 
ImageTranscodingCase(TestContext & testCtx,const std::string & name,const TestParameters & parameters)734 ImageTranscodingCase::ImageTranscodingCase (TestContext& testCtx, const std::string& name, const TestParameters& parameters)
735 	: TestCase				(testCtx, name)
736 	, m_parameters			(parameters)
737 {
738 }
739 
initPrograms(vk::SourceCollections & programCollection) const740 void ImageTranscodingCase::initPrograms (vk::SourceCollections&	programCollection) const
741 {
742 	DE_ASSERT(m_parameters.size.x() > 0);
743 	DE_ASSERT(m_parameters.size.y() > 0);
744 
745 	ImageType	imageTypeForFS = (m_parameters.imageType == IMAGE_TYPE_2D_ARRAY) ? IMAGE_TYPE_2D : m_parameters.imageType;
746 
747 	// Vertex shader
748 	{
749 		std::ostringstream src;
750 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
751 			<< "layout(location = 0) in vec4 v_in_position;\n"
752 			<< "\n"
753 			<< "void main (void)\n"
754 			<< "{\n"
755 			<< "    gl_Position = v_in_position;\n"
756 			<< "}\n";
757 
758 		programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
759 	}
760 
761 	// Fragment shader
762 	{
763 		switch(m_parameters.operation)
764 		{
765 			case OPERATION_ATTACHMENT_READ:
766 			case OPERATION_ATTACHMENT_WRITE:
767 			{
768 				std::ostringstream	src;
769 
770 				const std::string	dstTypeStr	= getGlslAttachmentType(m_parameters.featuredFormat);
771 				const std::string	srcTypeStr	= getGlslInputAttachmentType(m_parameters.featuredFormat);
772 
773 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
774 					<< "precision highp int;\n"
775 					<< "precision highp float;\n"
776 					<< "\n"
777 					<< "layout (location = 0) out highp " << dstTypeStr << " o_color;\n"
778 					<< "layout (input_attachment_index = 0, set = 0, binding = 0) uniform highp " << srcTypeStr << " inputImage1;\n"
779 					<< "\n"
780 					<< "void main (void)\n"
781 					<< "{\n"
782 					<< "    o_color = " << dstTypeStr << "(subpassLoad(inputImage1));\n"
783 					<< "}\n";
784 
785 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
786 
787 				break;
788 			}
789 
790 			case OPERATION_TEXTURE_READ:
791 			case OPERATION_TEXTURE_WRITE:
792 			{
793 				std::ostringstream	src;
794 
795 				const std::string	srcSamplerTypeStr		= getGlslSamplerType(mapVkFormat(m_parameters.featuredFormat), mapImageViewType(imageTypeForFS));
796 				const std::string	dstImageTypeStr			= getShaderImageType(mapVkFormat(m_parameters.featuredFormat), imageTypeForFS);
797 				const std::string	dstFormatQualifierStr	= getShaderImageFormatQualifier(mapVkFormat(m_parameters.featuredFormat));
798 
799 				src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n\n"
800 					<< "layout (binding = 0) uniform " << srcSamplerTypeStr << " u_imageIn;\n"
801 					<< "layout (binding = 1, " << dstFormatQualifierStr << ") writeonly uniform " << dstImageTypeStr << " u_imageOut;\n"
802 					<< "\n"
803 					<< "void main (void)\n"
804 					<< "{\n"
805 					<< "    const ivec2 out_pos = ivec2(gl_FragCoord.xy);\n"
806 					<< "    const vec2 pixels_resolution = vec2(textureSize(u_imageIn, 0));\n"
807 					<< "    const vec2 in_pos = vec2(gl_FragCoord.xy) / vec2(pixels_resolution);\n"
808 					<< "    imageStore(u_imageOut, out_pos, texture(u_imageIn, in_pos));\n"
809 					<< "}\n";
810 
811 				programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
812 
813 				break;
814 			}
815 
816 			default:
817 				DE_ASSERT(false);
818 		}
819 	}
820 }
821 
isFormatUsageFlagSupported(Context & context,const VkFormat format,VkImageUsageFlags formatUsageFlags) const822 bool ImageTranscodingCase::isFormatUsageFlagSupported (Context& context, const VkFormat format, VkImageUsageFlags formatUsageFlags) const
823 {
824 	const VkPhysicalDevice		physicalDevice			= context.getPhysicalDevice();
825 	const InstanceInterface&	vk						= context.getInstanceInterface();
826 	VkImageFormatProperties		imageFormatProperties;
827 	const VkResult				queryResult				= vk.getPhysicalDeviceImageFormatProperties(
828 															physicalDevice,
829 															format,
830 															mapImageType(m_parameters.imageType),
831 															VK_IMAGE_TILING_OPTIMAL,
832 															formatUsageFlags,
833 															VK_IMAGE_CREATE_EXTENDED_USAGE_BIT,
834 															&imageFormatProperties);
835 
836 	return (queryResult == VK_SUCCESS);
837 }
838 
checkSupport(Context & context) const839 void ImageTranscodingCase::checkSupport (Context& context) const
840 {
841 	context.requireDeviceFunctionality("VK_KHR_maintenance2");
842 
843 	if ((m_parameters.operation == OPERATION_TEXTURE_READ || m_parameters.operation == OPERATION_TEXTURE_WRITE) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
844 		TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
845 
846 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsageFeature))
847 		TCU_THROW(NotSupportedError, "Test skipped due to feature is not supported by the format");
848 
849 	if (!isFormatUsageFlagSupported(context, m_parameters.featuredFormat, m_parameters.testedImageUsage | m_parameters.pairedImageUsage))
850 		TCU_THROW(NotSupportedError, "Required image usage flags are not supported by the format");
851 }
852 
createInstance(Context & context) const853 TestInstance* ImageTranscodingCase::createInstance (Context& context) const
854 {
855 	VkFormat					featurelessFormat	= VK_FORMAT_UNDEFINED;
856 	bool						differenceFound		= false;
857 
858 	DE_ASSERT(m_parameters.testedImageUsageFeature != 0);
859 
860 	for (deUint32 i = 0; m_parameters.compatibleFormats[i] != VK_FORMAT_UNDEFINED; i++)
861 	{
862 		featurelessFormat = m_parameters.compatibleFormats[i];
863 
864 		if (isSupportedByFramework(featurelessFormat)
865 			&& !isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsageFeature)
866 			&& isFormatUsageFlagSupported(context, featurelessFormat, m_parameters.testedImageUsage & (~m_parameters.testedImageUsageFeature))
867 			)
868 		{
869 			differenceFound = true;
870 
871 			break;
872 		}
873 	}
874 
875 	if (differenceFound)
876 	{
877 #ifndef CTS_USES_VULKANSC
878 		if ((context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
879 			!context.getPortabilitySubsetFeatures().imageViewFormatReinterpretation))
880 		{
881 			tcu::TextureFormat	textureImageFormat	= vk::mapVkFormat(m_parameters.featuredFormat);
882 			tcu::TextureFormat	textureViewFormat	= vk::mapVkFormat(featurelessFormat);
883 
884 			if (tcu::getTextureFormatBitDepth(textureImageFormat) != tcu::getTextureFormatBitDepth(textureViewFormat))
885 				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");
886 		}
887 #endif // CTS_USES_VULKANSC
888 
889 		TestParameters	calculatedParameters	=
890 		{
891 			m_parameters.operation,					// Operation				operation
892 			m_parameters.size,						// UVec3					size
893 			m_parameters.imageType,					// ImageType				imageType
894 			m_parameters.testedImageUsageFeature,	// VkImageUsageFlagBits		testedImageUsageFeature
895 			m_parameters.featuredFormat,			// VkFormat					featuredFormat
896 			featurelessFormat,						// VkFormat					featurelessFormat
897 			m_parameters.testedImageUsage,			// VkImageUsageFlags		testedImageUsage
898 			m_parameters.pairedImageUsage,			// VkImageUsageFlags		pairedImageUsage
899 			DE_NULL,								// const VkFormat*			compatibleFormats
900 		};
901 
902 		switch (m_parameters.operation)
903 		{
904 			case OPERATION_ATTACHMENT_READ:
905 			case OPERATION_ATTACHMENT_WRITE:
906 				return new GraphicsAttachmentsTestInstance(context, calculatedParameters);
907 
908 			case OPERATION_TEXTURE_READ:
909 			case OPERATION_TEXTURE_WRITE:
910 				return new GraphicsTextureTestInstance(context, calculatedParameters);
911 
912 			default:
913 				TCU_THROW(InternalError, "Impossible");
914 		}
915 	}
916 	else
917 		TCU_THROW(NotSupportedError, "All formats in group contain tested feature. Test is impossible.");
918 }
919 
920 } // anonymous ns
921 
922 static const VkFormat	compatibleFormatList8Bit[]		=
923 {
924 	VK_FORMAT_R4G4_UNORM_PACK8,
925 	VK_FORMAT_R8_UNORM,
926 	VK_FORMAT_R8_SNORM,
927 	VK_FORMAT_R8_USCALED,
928 	VK_FORMAT_R8_SSCALED,
929 	VK_FORMAT_R8_UINT,
930 	VK_FORMAT_R8_SINT,
931 	VK_FORMAT_R8_SRGB,
932 
933 	VK_FORMAT_UNDEFINED
934 };
935 
936 static const VkFormat	compatibleFormatList16Bit[]		=
937 {
938 	VK_FORMAT_R4G4B4A4_UNORM_PACK16,
939 	VK_FORMAT_B4G4R4A4_UNORM_PACK16,
940 	VK_FORMAT_R5G6B5_UNORM_PACK16,
941 	VK_FORMAT_B5G6R5_UNORM_PACK16,
942 	VK_FORMAT_R5G5B5A1_UNORM_PACK16,
943 	VK_FORMAT_B5G5R5A1_UNORM_PACK16,
944 	VK_FORMAT_A1R5G5B5_UNORM_PACK16,
945 	VK_FORMAT_R8G8_UNORM,
946 	VK_FORMAT_R8G8_SNORM,
947 	VK_FORMAT_R8G8_USCALED,
948 	VK_FORMAT_R8G8_SSCALED,
949 	VK_FORMAT_R8G8_UINT,
950 	VK_FORMAT_R8G8_SINT,
951 	VK_FORMAT_R8G8_SRGB,
952 	VK_FORMAT_R16_UNORM,
953 	VK_FORMAT_R16_SNORM,
954 	VK_FORMAT_R16_USCALED,
955 	VK_FORMAT_R16_SSCALED,
956 	VK_FORMAT_R16_UINT,
957 	VK_FORMAT_R16_SINT,
958 	VK_FORMAT_R16_SFLOAT,
959 	VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
960 	VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
961 
962 	VK_FORMAT_UNDEFINED
963 };
964 
965 static const VkFormat	compatibleFormatList24Bit[]		=
966 {
967 	VK_FORMAT_R8G8B8_UNORM,
968 	VK_FORMAT_R8G8B8_SNORM,
969 	VK_FORMAT_R8G8B8_USCALED,
970 	VK_FORMAT_R8G8B8_SSCALED,
971 	VK_FORMAT_R8G8B8_UINT,
972 	VK_FORMAT_R8G8B8_SINT,
973 	VK_FORMAT_R8G8B8_SRGB,
974 	VK_FORMAT_B8G8R8_UNORM,
975 	VK_FORMAT_B8G8R8_SNORM,
976 	VK_FORMAT_B8G8R8_USCALED,
977 	VK_FORMAT_B8G8R8_SSCALED,
978 	VK_FORMAT_B8G8R8_UINT,
979 	VK_FORMAT_B8G8R8_SINT,
980 	VK_FORMAT_B8G8R8_SRGB,
981 
982 	VK_FORMAT_UNDEFINED
983 };
984 
985 static const VkFormat	compatibleFormatList32Bit[]		=
986 {
987 	VK_FORMAT_R8G8B8A8_UNORM,
988 	VK_FORMAT_R8G8B8A8_SNORM,
989 	VK_FORMAT_R8G8B8A8_USCALED,
990 	VK_FORMAT_R8G8B8A8_SSCALED,
991 	VK_FORMAT_R8G8B8A8_UINT,
992 	VK_FORMAT_R8G8B8A8_SINT,
993 	VK_FORMAT_R8G8B8A8_SRGB,
994 	VK_FORMAT_B8G8R8A8_UNORM,
995 	VK_FORMAT_B8G8R8A8_SNORM,
996 	VK_FORMAT_B8G8R8A8_USCALED,
997 	VK_FORMAT_B8G8R8A8_SSCALED,
998 	VK_FORMAT_B8G8R8A8_UINT,
999 	VK_FORMAT_B8G8R8A8_SINT,
1000 	VK_FORMAT_B8G8R8A8_SRGB,
1001 	VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1002 	VK_FORMAT_A8B8G8R8_SNORM_PACK32,
1003 	VK_FORMAT_A8B8G8R8_USCALED_PACK32,
1004 	VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
1005 	VK_FORMAT_A8B8G8R8_UINT_PACK32,
1006 	VK_FORMAT_A8B8G8R8_SINT_PACK32,
1007 	VK_FORMAT_A8B8G8R8_SRGB_PACK32,
1008 	VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1009 	VK_FORMAT_A2R10G10B10_SNORM_PACK32,
1010 	VK_FORMAT_A2R10G10B10_USCALED_PACK32,
1011 	VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
1012 	VK_FORMAT_A2R10G10B10_UINT_PACK32,
1013 	VK_FORMAT_A2R10G10B10_SINT_PACK32,
1014 	VK_FORMAT_A2B10G10R10_UNORM_PACK32,
1015 	VK_FORMAT_A2B10G10R10_SNORM_PACK32,
1016 	VK_FORMAT_A2B10G10R10_USCALED_PACK32,
1017 	VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
1018 	VK_FORMAT_A2B10G10R10_UINT_PACK32,
1019 	VK_FORMAT_A2B10G10R10_SINT_PACK32,
1020 	VK_FORMAT_R16G16_UNORM,
1021 	VK_FORMAT_R16G16_SNORM,
1022 	VK_FORMAT_R16G16_USCALED,
1023 	VK_FORMAT_R16G16_SSCALED,
1024 	VK_FORMAT_R16G16_UINT,
1025 	VK_FORMAT_R16G16_SINT,
1026 	VK_FORMAT_R16G16_SFLOAT,
1027 	VK_FORMAT_R32_UINT,
1028 	VK_FORMAT_R32_SINT,
1029 	VK_FORMAT_R32_SFLOAT,
1030 
1031 	VK_FORMAT_UNDEFINED
1032 };
1033 
1034 static const VkFormat	compatibleFormatList48Bit[]		=
1035 {
1036 	VK_FORMAT_R16G16B16_UNORM,
1037 	VK_FORMAT_R16G16B16_SNORM,
1038 	VK_FORMAT_R16G16B16_USCALED,
1039 	VK_FORMAT_R16G16B16_SSCALED,
1040 	VK_FORMAT_R16G16B16_UINT,
1041 	VK_FORMAT_R16G16B16_SINT,
1042 	VK_FORMAT_R16G16B16_SFLOAT,
1043 
1044 	VK_FORMAT_UNDEFINED
1045 };
1046 
1047 static const VkFormat	compatibleFormatList64Bit[]		=
1048 {
1049 	VK_FORMAT_R16G16B16A16_UNORM,
1050 	VK_FORMAT_R16G16B16A16_SNORM,
1051 	VK_FORMAT_R16G16B16A16_USCALED,
1052 	VK_FORMAT_R16G16B16A16_SSCALED,
1053 	VK_FORMAT_R16G16B16A16_UINT,
1054 	VK_FORMAT_R16G16B16A16_SINT,
1055 	VK_FORMAT_R16G16B16A16_SFLOAT,
1056 	VK_FORMAT_R32G32_UINT,
1057 	VK_FORMAT_R32G32_SINT,
1058 	VK_FORMAT_R32G32_SFLOAT,
1059 	VK_FORMAT_R64_UINT,
1060 	VK_FORMAT_R64_SINT,
1061 	VK_FORMAT_R64_SFLOAT,
1062 
1063 	VK_FORMAT_UNDEFINED
1064 };
1065 
1066 static const VkFormat	compatibleFormatList96Bit[]		=
1067 {
1068 	VK_FORMAT_R32G32B32_UINT,
1069 	VK_FORMAT_R32G32B32_SINT,
1070 	VK_FORMAT_R32G32B32_SFLOAT,
1071 
1072 	VK_FORMAT_UNDEFINED
1073 };
1074 
1075 static const VkFormat	compatibleFormatList128Bit[]	=
1076 {
1077 	VK_FORMAT_R32G32B32A32_UINT,
1078 	VK_FORMAT_R32G32B32A32_SINT,
1079 	VK_FORMAT_R32G32B32A32_SFLOAT,
1080 	VK_FORMAT_R64G64_UINT,
1081 	VK_FORMAT_R64G64_SINT,
1082 	VK_FORMAT_R64G64_SFLOAT,
1083 
1084 	VK_FORMAT_UNDEFINED
1085 };
1086 
1087 const VkFormat	compatibleFormatList192Bit[]	=
1088 {
1089 	VK_FORMAT_R64G64B64_UINT,
1090 	VK_FORMAT_R64G64B64_SINT,
1091 	VK_FORMAT_R64G64B64_SFLOAT,
1092 
1093 	VK_FORMAT_UNDEFINED
1094 };
1095 
1096 static const VkFormat	compatibleFormatList256Bit[]	=
1097 {
1098 	VK_FORMAT_R64G64B64A64_UINT,
1099 	VK_FORMAT_R64G64B64A64_SINT,
1100 	VK_FORMAT_R64G64B64A64_SFLOAT,
1101 
1102 	VK_FORMAT_UNDEFINED
1103 };
1104 
1105 static const VkFormat*	compatibleFormatsList[]	=
1106 {
1107 	compatibleFormatList8Bit,
1108 	compatibleFormatList16Bit,
1109 	compatibleFormatList24Bit,
1110 	compatibleFormatList32Bit,
1111 	compatibleFormatList48Bit,
1112 	compatibleFormatList64Bit,
1113 	compatibleFormatList96Bit,
1114 	compatibleFormatList128Bit,
1115 	compatibleFormatList192Bit,
1116 	compatibleFormatList256Bit,
1117 };
1118 
createImageTranscodingSupportTests(tcu::TestContext & testCtx)1119 tcu::TestCaseGroup* createImageTranscodingSupportTests (tcu::TestContext& testCtx)
1120 {
1121 	const std::string			operationName[OPERATION_LAST]			=
1122 	{
1123 		"attachment_read",
1124 		"attachment_write",
1125 		"texture_read",
1126 		"texture_write",
1127 	};
1128 	const VkImageUsageFlagBits	testedImageUsageFlags[OPERATION_LAST]	=
1129 	{
1130 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1131 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1132 		VK_IMAGE_USAGE_SAMPLED_BIT,
1133 		VK_IMAGE_USAGE_STORAGE_BIT,
1134 	};
1135 	const VkImageUsageFlagBits	pairedImageUsageFlags[OPERATION_LAST]	=
1136 	{
1137 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
1138 		VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
1139 		VK_IMAGE_USAGE_STORAGE_BIT,
1140 		VK_IMAGE_USAGE_SAMPLED_BIT,
1141 	};
1142 	VkImageUsageFlags			baseFlagsAddOn							= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
1143 
1144 	MovePtr<tcu::TestCaseGroup>	imageTranscodingTests	(new tcu::TestCaseGroup(testCtx, "extended_usage_bit"));
1145 
1146 	for (int operationNdx = OPERATION_ATTACHMENT_READ; operationNdx < OPERATION_LAST; ++operationNdx)
1147 	{
1148 		MovePtr<tcu::TestCaseGroup>	imageOperationGroup	(new tcu::TestCaseGroup(testCtx, operationName[operationNdx].c_str()));
1149 
1150 		for (deUint32 groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(compatibleFormatsList); groupNdx++)
1151 		{
1152 			for (deUint32 featuredFormatNdx = 0; compatibleFormatsList[groupNdx][featuredFormatNdx] != VK_FORMAT_UNDEFINED; featuredFormatNdx++)
1153 			{
1154 				const VkFormat	featuredFormat		= compatibleFormatsList[groupNdx][featuredFormatNdx];
1155 				const VkFormat	featurelessFormat	= VK_FORMAT_UNDEFINED;									// Lookup process is in createInstance()
1156 
1157 				if (!isSupportedByFramework(featuredFormat))
1158 					continue;
1159 
1160 				// Cannot handle SRGB in shader layout classifier
1161 				if (isSrgbFormat(featuredFormat))
1162 					continue;
1163 
1164 				// Cannot handle packed in shader layout classifier
1165 				if (isPackedType(featuredFormat))
1166 					continue;
1167 
1168 				// Cannot handle swizzled component format (i.e. bgr) in shader layout classifier
1169 				if (isComponentSwizzled(featuredFormat))
1170 					continue;
1171 
1172 				// Cannot handle three-component images in shader layout classifier
1173 				if (getNumUsedChannels(featuredFormat) == 3)
1174 					continue;
1175 
1176 				const std::string		testName	= getFormatShortString(featuredFormat);
1177 				const TestParameters	parameters	=
1178 				{
1179 					static_cast<Operation>(operationNdx),					// Operation				operation
1180 					UVec3(16u, 16u, 1u),									// UVec3					size
1181 					IMAGE_TYPE_2D,											// ImageType				imageType
1182 					testedImageUsageFlags[operationNdx],					// VkImageUsageFlagBits		testedImageUsageFeature
1183 					featuredFormat,											// VkFormat					featuredFormat
1184 					featurelessFormat,										// VkFormat					featurelessFormat
1185 					baseFlagsAddOn | testedImageUsageFlags[operationNdx],	// VkImageUsageFlags		testedImageUsage
1186 					baseFlagsAddOn | pairedImageUsageFlags[operationNdx],	// VkImageUsageFlags		pairedImageUsage
1187 					compatibleFormatsList[groupNdx]							// const VkFormat*			compatibleFormats
1188 				};
1189 
1190 				imageOperationGroup->addChild(new ImageTranscodingCase(testCtx, testName, parameters));
1191 			}
1192 		}
1193 
1194 		imageTranscodingTests->addChild(imageOperationGroup.release());
1195 	}
1196 
1197 	return imageTranscodingTests.release();
1198 }
1199 
1200 } // image
1201 } // vkt
1202