• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Valve Corporation.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Tests vkCmdClearAttachments with unused attachments.
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vktRenderPassTestsUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include <sstream>
35 #include <functional>
36 #include <vector>
37 #include <string>
38 #include <memory>
39 
40 namespace vkt
41 {
42 namespace renderpass
43 {
44 
45 namespace
46 {
47 
48 constexpr size_t	COLOR_ATTACHMENTS_NUMBER	= 4; // maxColorAttachments is guaranteed to be at least 4.
49 constexpr VkFormat	FORMAT_COLOR				= VK_FORMAT_R8G8B8A8_UNORM;
50 constexpr VkFormat	FORMAT_DEPTH				= VK_FORMAT_D32_SFLOAT;
51 constexpr VkFormat	FORMAT_STENCIL				= VK_FORMAT_S8_UINT;
52 constexpr VkFormat	FORMAT_DEPTH_STENCIL		= VK_FORMAT_D32_SFLOAT_S8_UINT;
53 const deBool		DE_BOOL_VALUES[]			= { DE_FALSE, DE_TRUE };
54 
55 enum DepthStencilType
56 {
57 	DEPTH_STENCIL_NONE			= 0,
58 	DEPTH_STENCIL_DEPTH_ONLY	= 1,
59 	DEPTH_STENCIL_STENCIL_ONLY	= 2,
60 	DEPTH_STENCIL_BOTH			= 3,
61 	DEPTH_STENCIL_MAX_ENUM		= 4
62 };
63 
getFormatBriefName(VkFormat format)64 std::string getFormatBriefName (VkFormat format)
65 {
66 	switch (format)
67 	{
68 	case VK_FORMAT_D32_SFLOAT:			return "d32";
69 	case VK_FORMAT_S8_UINT:				return "s8";
70 	case VK_FORMAT_D32_SFLOAT_S8_UINT:	return "d32s8";
71 	default:								break;
72 	}
73 
74 	return "";
75 }
76 
depthStencilTypeName(DepthStencilType type,VkFormat format)77 std::string depthStencilTypeName (DepthStencilType type, VkFormat format)
78 {
79 	DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
80 
81 	const std::string formatName = getFormatBriefName(format);
82 
83 	switch (type)
84 	{
85 	case DEPTH_STENCIL_NONE:			return "nods";
86 	case DEPTH_STENCIL_DEPTH_ONLY:		return "depthonly_" + formatName;
87 	case DEPTH_STENCIL_STENCIL_ONLY:	return "stencilonly_" + formatName;
88 	case DEPTH_STENCIL_BOTH:			return "depthstencil_" + formatName;
89 	default:							return "UNKNOWN";		// Unreachable.
90 	}
91 
92 	return "UNKNOWN";											// Unreachable.
93 }
94 
getClearAspectMask(DepthStencilType type)95 VkImageAspectFlags getClearAspectMask (DepthStencilType type)
96 {
97 	VkImageAspectFlags aspectMask = 0u;
98 
99 	if (type == DEPTH_STENCIL_DEPTH_ONLY || type == DEPTH_STENCIL_BOTH)
100 		aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
101 
102 	if (type == DEPTH_STENCIL_STENCIL_ONLY || type == DEPTH_STENCIL_BOTH)
103 		aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
104 
105 	return aspectMask;
106 }
107 
getFormatAspectMask(VkFormat format)108 VkImageAspectFlags getFormatAspectMask (VkFormat format)
109 {
110 	const auto			order		= mapVkFormat(format).order;
111 	VkImageAspectFlags	aspectMask	= 0u;
112 
113 	if (tcu::hasDepthComponent(order))
114 		aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
115 
116 	if (tcu::hasStencilComponent(order))
117 		aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
118 
119 	if (!aspectMask)
120 		aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT;
121 
122 	return aspectMask;
123 }
124 
getFormats(DepthStencilType type)125 std::vector<VkFormat> getFormats (DepthStencilType type)
126 {
127 	DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
128 
129 	std::vector<VkFormat> formats;
130 
131 	if (type != DEPTH_STENCIL_NONE)
132 		formats.push_back(FORMAT_DEPTH_STENCIL);
133 	else
134 		formats.push_back(VK_FORMAT_UNDEFINED);
135 
136 	if (type == DEPTH_STENCIL_DEPTH_ONLY)
137 		formats.push_back(FORMAT_DEPTH);
138 	else if (type == DEPTH_STENCIL_STENCIL_ONLY)
139 		formats.push_back(FORMAT_STENCIL);
140 
141 	return formats;
142 }
143 
isDepthOnly(DepthStencilType type)144 bool isDepthOnly(DepthStencilType type)
145 {
146 	return (type == DEPTH_STENCIL_DEPTH_ONLY);
147 }
148 
isStencilOnly(DepthStencilType type)149 bool isStencilOnly(DepthStencilType type)
150 {
151 	return (type == DEPTH_STENCIL_STENCIL_ONLY);
152 }
153 
hasDepthStencil(DepthStencilType type)154 bool hasDepthStencil(DepthStencilType type)
155 {
156 	return (type != DEPTH_STENCIL_NONE);
157 }
158 
159 struct TestParams
160 {
TestParamsvkt::renderpass::__anon8b825e940111::TestParams161 	TestParams(size_t numColorAttachments, DepthStencilType depthStencilType_, deBool depthStencilUsed_, VkFormat depthStencilFormat_, const SharedGroupParams groupParams_)
162 		: colorUsed(numColorAttachments, DE_FALSE)
163 		, depthStencilType(depthStencilType_)
164 		, depthStencilUsed(depthStencilUsed_)
165 		, depthStencilFormat(depthStencilFormat_)
166 		, groupParams(groupParams_)
167 		{}
168 
169 	std::vector<deBool>		colorUsed;
170 	DepthStencilType		depthStencilType;
171 	deBool					depthStencilUsed;
172 	VkFormat				depthStencilFormat;
173 	const SharedGroupParams	groupParams;
174 };
175 
176 class UnusedClearAttachmentTestInstance : public vkt::TestInstance
177 {
178 public:
179 											UnusedClearAttachmentTestInstance	(Context&			context,
180 																				 const TestParams&	testParams);
~UnusedClearAttachmentTestInstance(void)181 	virtual									~UnusedClearAttachmentTestInstance	(void) {}
182 	virtual tcu::TestStatus					iterate								(void);
183 	template<typename RenderpassSubpass>
184 	void									createCommandBuffer					(const DeviceInterface&	vk,
185 																				 VkDevice				vkDevice);
186 
187 #ifndef CTS_USES_VULKANSC
188 	void									createCommandBufferDynamicRendering	(const DeviceInterface&	vk,
189 																				 VkDevice				vkDevice);
190 #endif // CTS_USES_VULKANSC
191 
192 private:
193 	static constexpr deUint32				kImageWidth		= 32;
194 	static constexpr deUint32				kImageHeight	= 32;
195 	const tcu::UVec2						m_renderSize	= { kImageWidth, kImageHeight };
196 
197 	VkClearValue							m_initialColor;
198 	VkClearValue							m_initialColorDepth;
199 	VkClearValue							m_clearColor;
200 	VkClearValue							m_clearColorDepth;
201 
202 	const TestParams						m_testParams;
203 
204 	std::vector<Move<VkImage>>				m_colorImages;
205 	std::vector<de::MovePtr<Allocation>>	m_colorImageAllocs;
206 	std::vector<Move<VkImageView>>			m_colorAttachmentViews;
207 
208 	Move<VkImage>							m_depthImage;
209 	de::MovePtr<Allocation>					m_depthImageAlloc;
210 	Move<VkImageView>						m_depthAttachmentView;
211 
212 	Move<VkRenderPass>						m_renderPass;
213 	Move<VkFramebuffer>						m_framebuffer;
214 	Move<VkShaderModule>					m_vertexShaderModule;
215 	Move<VkShaderModule>					m_fragmentShaderModule;
216 	Move<VkDescriptorSetLayout>				m_descriptorSetLayout;
217 	Move<VkPipelineLayout>					m_pipelineLayout;
218 	Move<VkPipeline>						m_graphicsPipeline;
219 	Move<VkCommandPool>						m_cmdPool;
220 	Move<VkCommandBuffer>					m_cmdBuffer;
221 	Move<VkCommandBuffer>					m_secCmdBuffer;
222 };
223 
224 class UnusedClearAttachmentTest : public vkt::TestCase
225 {
226 public:
UnusedClearAttachmentTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const TestParams & testParams)227 										UnusedClearAttachmentTest	(tcu::TestContext&	testContext,
228 																	 const std::string&	name,
229 																	 const std::string&	description,
230 																	 const TestParams&	testParams)
231 											: vkt::TestCase(testContext, name, description)
232 											, m_testParams(testParams)
233 											{}
~UnusedClearAttachmentTest(void)234 	virtual								~UnusedClearAttachmentTest	(void) {}
235 	virtual void						initPrograms				(SourceCollections&	sourceCollections) const;
236 	virtual TestInstance*				createInstance				(Context&			context) const;
237 	virtual void						checkSupport				(Context&			context) const;
238 private:
239 	const TestParams					m_testParams;
240 };
241 
checkFormatSupported(Context & context,VkFormat format,VkImageUsageFlags usage)242 void checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage)
243 {
244 	VkResult					result;
245 	VkImageFormatProperties		properties;
246 
247 	result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
248 		context.getPhysicalDevice(), format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
249 
250 	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
251 	{
252 		std::ostringstream msg;
253 		msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
254 		TCU_THROW(NotSupportedError, msg.str());
255 	}
256 
257 	VK_CHECK(result);
258 }
259 
checkSupport(Context & context) const260 void UnusedClearAttachmentTest::checkSupport (Context& context) const
261 {
262 	// Check for renderpass2 extension if used
263 	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
264 		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
265 
266 	// Check for dynamic_rendering extension if used
267 	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
268 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
269 
270 	// Check support for the needed color, depth and stencil formats.
271 	if (!m_testParams.colorUsed.empty())
272 		checkFormatSupported(context, FORMAT_COLOR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
273 
274 	if (hasDepthStencil(m_testParams.depthStencilType))
275 		checkFormatSupported(context, m_testParams.depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
276 }
277 
createInstance(Context & context) const278 TestInstance* UnusedClearAttachmentTest::createInstance (Context& context) const
279 {
280 	return new UnusedClearAttachmentTestInstance(context, m_testParams);
281 }
282 
283 // These shaders are needed to create the graphics pipeline, but they will not be actually used because we will not draw anything.
initPrograms(SourceCollections & sourceCollections) const284 void UnusedClearAttachmentTest::initPrograms (SourceCollections& sourceCollections) const
285 {
286 	// Vertex shader.
287 	sourceCollections.glslSources.add("vert_shader") << glu::VertexSource(
288 		"#version 450\n"
289 		"precision highp float;\n"
290 		"layout(location = 0) in vec4 position;\n"
291 		"layout(location = 0) out vec4 vtxColor;\n"
292 		"void main (void)\n"
293 		"{\n"
294 		"\tgl_Position = position;\n"
295 		"\tvtxColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
296 		"}\n");
297 
298 	// Fragment shader.
299 	std::ostringstream fragmentSource;
300 
301 	fragmentSource	<< "#version 450\n"
302 					<< "precision highp float;\n"
303 					<< "layout(location = 0) in vec4 vtxColor;\n";
304 
305 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
306 	{
307 		if (m_testParams.colorUsed[i])
308 			fragmentSource << "layout(location = " << i << ") out vec4 fragColor" << i << ";\n";
309 	}
310 
311 	fragmentSource	<< "void main (void)\n"
312 					<< "{\n";
313 
314 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
315 	{
316 		if (m_testParams.colorUsed[i])
317 			fragmentSource << "\tfragColor" << i << " = vtxColor;\n";
318 	}
319 
320 	fragmentSource	<< "}\n";
321 
322 	sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
323 }
324 
325 // Create a render pass for this use case.
326 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,const TestParams testParams)327 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk,
328 									 VkDevice				vkDevice,
329 									 const TestParams		testParams)
330 {
331 	const VkImageAspectFlags	colorAspectMask					= VK_IMAGE_ASPECT_COLOR_BIT;
332 	const VkImageAspectFlags	dsClearAspectMask				= getClearAspectMask(testParams.depthStencilType);
333 	const bool					isDepthStencil					= hasDepthStencil(testParams.depthStencilType);
334 
335 	// Create attachment descriptions.
336 	const AttachmentDesc		attachmentDescription			(
337 		DE_NULL,									// const void*						pNext
338 		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags
339 		FORMAT_COLOR,								// VkFormat							format
340 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples
341 		VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				loadOp
342 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp
343 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp
344 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp
345 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
346 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
347 	);
348 	std::vector<AttachmentDesc>	attachmentDescriptions			(testParams.colorUsed.size(), attachmentDescription);
349 
350 	if (isDepthStencil)
351 	{
352 		const bool					depthOnly		= isDepthOnly(testParams.depthStencilType);
353 		const bool					stencilOnly		= isStencilOnly(testParams.depthStencilType);
354 		const VkAttachmentLoadOp	depthLoadOp		= (stencilOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
355 		const VkAttachmentStoreOp	depthStoreOp	= (stencilOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
356 		const VkAttachmentLoadOp	stencilLoadOp	= (depthOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
357 		const VkAttachmentStoreOp	stencilStoreOp	= (depthOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
358 
359 		attachmentDescriptions.emplace_back(
360 			nullptr,											// const void*						pNext
361 			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
362 			testParams.depthStencilFormat,						// VkFormat							format
363 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples
364 			depthLoadOp,										// VkAttachmentLoadOp				loadOp
365 			depthStoreOp,										// VkAttachmentStoreOp				storeOp
366 			stencilLoadOp,										// VkAttachmentLoadOp				stencilLoadOp
367 			stencilStoreOp,										// VkAttachmentStoreOp				stencilStoreOp
368 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
369 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
370 		);
371 	}
372 
373 	// Mark attachments as used or not depending on the test parameters.
374 	std::vector<AttachmentRef>		attachmentReferences;
375 	for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
376 	{
377 		attachmentReferences.push_back(AttachmentRef(
378 			DE_NULL,																		// const void*			pNext
379 			(testParams.colorUsed[i] ? static_cast<deUint32>(i) : VK_ATTACHMENT_UNUSED),	// deUint32				attachment
380 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout		layout
381 			colorAspectMask																	// VkImageAspectFlags	aspectMask
382 		));
383 	}
384 
385 	std::unique_ptr<AttachmentRef>	depthAttachmentRef;
386 	if (isDepthStencil)
387 	{
388 		depthAttachmentRef.reset(new AttachmentRef(
389 			DE_NULL,
390 			(testParams.depthStencilUsed ? static_cast<deUint32>(testParams.colorUsed.size()) : VK_ATTACHMENT_UNUSED),
391 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
392 			dsClearAspectMask
393 		));
394 	}
395 
396 	// Create subpass description with the previous color attachment references.
397 	const SubpassDesc			subpassDescription				(
398 		DE_NULL,
399 		(VkSubpassDescriptionFlags)0,											// VkSubpassDescriptionFlags		flags
400 		VK_PIPELINE_BIND_POINT_GRAPHICS,										// VkPipelineBindPoint				pipelineBindPoint
401 		0u,																		// deUint32							viewMask
402 		0u,																		// deUint32							inputAttachmentCount
403 		DE_NULL,																// const VkAttachmentReference*		pInputAttachments
404 		static_cast<deUint32>(attachmentReferences.size()),						// deUint32							colorAttachmentCount
405 		(attachmentReferences.empty() ? DE_NULL : attachmentReferences.data()),	// const VkAttachmentReference*		pColorAttachments
406 		DE_NULL,																// const VkAttachmentReference*		pResolveAttachments
407 		(depthAttachmentRef ? depthAttachmentRef.get() : DE_NULL),				// const VkAttachmentReference*		pDepthStencilAttachment
408 		0u,																		// deUint32							preserveAttachmentCount
409 		DE_NULL																	// const deUint32*					pPreserveAttachments
410 	);
411 
412 	const RenderPassCreateInfo	renderPassInfo					(
413 		DE_NULL,																	// const void*						pNext
414 		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
415 		static_cast<deUint32>(attachmentDescriptions.size()),						// deUint32							attachmentCount
416 		(attachmentDescriptions.empty() ? DE_NULL : attachmentDescriptions.data()),	// const VkAttachmentDescription*	pAttachments
417 		1u,																			// deUint32							subpassCount
418 		&subpassDescription,														// const VkSubpassDescription*		pSubpasses
419 		0u,																			// deUint32							dependencyCount
420 		DE_NULL,																	// const VkSubpassDependency*		pDependencies
421 		0u,																			// deUint32							correlatedViewMaskCount
422 		DE_NULL																		// const deUint32*					pCorrelatedViewMasks
423 	);
424 
425 	return renderPassInfo.createRenderPass(vk, vkDevice);
426 }
427 
UnusedClearAttachmentTestInstance(Context & context,const TestParams & testParams)428 UnusedClearAttachmentTestInstance::UnusedClearAttachmentTestInstance(Context&			context,
429 																	 const TestParams&	testParams)
430 	: vkt::TestInstance(context)
431 	, m_testParams(testParams)
432 {
433 	// Initial color for all images.
434 	m_initialColor.color.float32[0] = 0.0f;
435 	m_initialColor.color.float32[1] = 0.0f;
436 	m_initialColor.color.float32[2] = 0.0f;
437 	m_initialColor.color.float32[3] = 1.0f;
438 
439 	m_initialColorDepth.depthStencil.depth = 1.0f;
440 	m_initialColorDepth.depthStencil.stencil = 0u;
441 
442 	// Clear color for used attachments.
443 	m_clearColor.color.float32[0] = 1.0f;
444 	m_clearColor.color.float32[1] = 1.0f;
445 	m_clearColor.color.float32[2] = 1.0f;
446 	m_clearColor.color.float32[3] = 1.0f;
447 
448 	m_clearColorDepth.depthStencil.depth = 0.0f;
449 	m_clearColorDepth.depthStencil.stencil = 255u;
450 
451 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
452 	const VkDevice				vkDevice				= m_context.getDevice();
453 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
454 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
455 	const VkComponentMapping	componentMapping		= { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
456 
457 	// Create color images.
458 	{
459 		const VkImageCreateInfo	colorImageParams =
460 		{
461 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
462 			DE_NULL,																// const void*				pNext;
463 			0u,																		// VkImageCreateFlags		flags;
464 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
465 			FORMAT_COLOR,															// VkFormat					format;
466 			{ kImageWidth, kImageHeight, 1u },										// VkExtent3D				extent;
467 			1u,																		// deUint32					mipLevels;
468 			1u,																		// deUint32					arrayLayers;
469 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
470 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
471 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
472 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
473 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
474 			1u,																		// deUint32					queueFamilyIndexCount;
475 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
476 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
477 		};
478 
479 		const VkImageCreateInfo depthImageParams =
480 		{
481 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
482 			DE_NULL,																		// const void*				pNext;
483 			0u,																				// VkImageCreateFlags		flags;
484 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
485 			m_testParams.depthStencilFormat,												// VkFormat					format;
486 			{ kImageWidth, kImageHeight, 1u },												// VkExtent3D				extent;
487 			1u,																				// deUint32					mipLevels;
488 			1u,																				// deUint32					arrayLayers;
489 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
490 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
491 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
492 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT,											// VkImageUsageFlags		usage;
493 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
494 			1u,																				// deUint32					queueFamilyIndexCount;
495 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
496 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
497 		};
498 
499 		for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
500 		{
501 			// Create, allocate and bind image memory.
502 			m_colorImages.emplace_back(createImage(vk, vkDevice, &colorImageParams));
503 			m_colorImageAllocs.emplace_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImages.back()), MemoryRequirement::Any));
504 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImages.back(), m_colorImageAllocs.back()->getMemory(), m_colorImageAllocs.back()->getOffset()));
505 
506 			// Create image view.
507 			{
508 				const VkImageViewCreateInfo colorAttachmentViewParams =
509 				{
510 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
511 					DE_NULL,											// const void*				pNext;
512 					0u,													// VkImageViewCreateFlags	flags;
513 					*m_colorImages.back(),								// VkImage					image;
514 					VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
515 					FORMAT_COLOR,										// VkFormat					format;
516 					componentMapping,									// VkChannelMapping			channels;
517 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
518 				};
519 
520 				m_colorAttachmentViews.emplace_back(createImageView(vk, vkDevice, &colorAttachmentViewParams));
521 			}
522 
523 			// Clear image and leave it prepared to be used as a color attachment.
524 			{
525 				const VkImageAspectFlags		aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
526 				Move<VkCommandPool>				cmdPool;
527 				Move<VkCommandBuffer>			cmdBuffer;
528 
529 				// Create command pool and buffer
530 				cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
531 				cmdBuffer	= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
532 
533 				// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
534 				const VkImageMemoryBarrier preImageBarrier =
535 				{
536 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
537 					DE_NULL,								// const void*				pNext;
538 					0u,										// VkAccessFlags			srcAccessMask;
539 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
540 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
541 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
542 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
543 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
544 					*m_colorImages.back(),					// VkImage					image;
545 					{										// VkImageSubresourceRange	subresourceRange;
546 						aspectMask,							// VkImageAspect			aspect;
547 						0u,									// deUint32					baseMipLevel;
548 						1u,									// deUint32					mipLevels;
549 						0u,									// deUint32					baseArraySlice;
550 						1u									// deUint32					arraySize;
551 					}
552 				};
553 
554 				// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
555 				const VkImageMemoryBarrier postImageBarrier =
556 				{
557 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
558 					DE_NULL,									// const void*				pNext;
559 					VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
560 					VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
561 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
562 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
563 					VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
564 					VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
565 					*m_colorImages.back(),						// VkImage					image;
566 					{											// VkImageSubresourceRange	subresourceRange;
567 						aspectMask,								// VkImageAspect			aspect;
568 						0u,										// deUint32					baseMipLevel;
569 						1u,										// deUint32					mipLevels;
570 						0u,										// deUint32					baseArraySlice;
571 						1u										// deUint32					arraySize;
572 					}
573 				};
574 
575 				const VkImageSubresourceRange clearRange	=
576 				{
577 					aspectMask,	// VkImageAspectFlags	aspectMask;
578 					0u,			// deUint32				baseMipLevel;
579 					1u,			// deUint32				levelCount;
580 					0u,			// deUint32				baseArrayLayer;
581 					1u			// deUint32				layerCount;
582 				};
583 
584 				// Clear image and transfer layout.
585 				beginCommandBuffer(vk, *cmdBuffer);
586 					vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
587 					vk.cmdClearColorImage(*cmdBuffer, *m_colorImages.back(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
588 					vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
589 				endCommandBuffer(vk, *cmdBuffer);
590 
591 				submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
592 			}
593 		}
594 
595 		if (hasDepthStencil(m_testParams.depthStencilType))
596 		{
597 			const VkImageAspectFlags clearAspectMask	= getClearAspectMask(m_testParams.depthStencilType);
598 			const VkImageAspectFlags formatAspectMask	= getFormatAspectMask(m_testParams.depthStencilFormat);
599 
600 			// Create, allocate and bind image memory.
601 			m_depthImage = createImage(vk, vkDevice, &depthImageParams);
602 			m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
603 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
604 
605 			// Create image view.
606 			{
607 				const VkImageViewCreateInfo depthAttachmentViewParams =
608 				{
609 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
610 					DE_NULL,									// const void*				pNext;
611 					0u,											// VkImageViewCreateFlags	flags;
612 					*m_depthImage,								// VkImage					image;
613 					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
614 					m_testParams.depthStencilFormat,			// VkFormat					format;
615 					componentMapping,							// VkChannelMapping			channels;
616 					{ clearAspectMask, 0u, 1u, 0u, 1u }			// VkImageSubresourceRange	subresourceRange;
617 				};
618 
619 				m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
620 			}
621 
622 			// Clear image and leave it prepared to be used as a depth/stencil attachment.
623 			{
624 				Move<VkCommandPool>				cmdPool;
625 				Move<VkCommandBuffer>			cmdBuffer;
626 
627 				// Create command pool and buffer
628 				cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
629 				cmdBuffer	= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
630 
631 				// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
632 				const VkImageMemoryBarrier		preImageBarrier =
633 				{
634 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
635 					DE_NULL,								// const void*				pNext;
636 					0u,										// VkAccessFlags			srcAccessMask;
637 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
638 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
639 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
640 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
641 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
642 					*m_depthImage,							// VkImage					image;
643 					{										// VkImageSubresourceRange	subresourceRange;
644 						formatAspectMask,					// VkImageAspect			aspect;
645 						0u,									// deUint32					baseMipLevel;
646 						1u,									// deUint32					mipLevels;
647 						0u,									// deUint32					baseArraySlice;
648 						1u									// deUint32					arraySize;
649 					}
650 				};
651 
652 				// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.
653 				const VkImageMemoryBarrier		postImageBarrier =
654 				{
655 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
656 					DE_NULL,											// const void*				pNext;
657 					VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask;
658 					VK_ACCESS_SHADER_READ_BIT,							// VkAccessFlags			dstAccessMask;
659 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
660 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
661 					VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
662 					VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
663 					*m_depthImage,										// VkImage					image;
664 					{													// VkImageSubresourceRange	subresourceRange;
665 						formatAspectMask,								// VkImageAspect			aspect;
666 						0u,												// deUint32					baseMipLevel;
667 						1u,												// deUint32					mipLevels;
668 						0u,												// deUint32					baseArraySlice;
669 						1u												// deUint32					arraySize;
670 					}
671 				};
672 
673 				const VkImageSubresourceRange	clearRange	=
674 				{
675 					clearAspectMask,	// VkImageAspectFlags	aspectMask;
676 					0u,					// deUint32				baseMipLevel;
677 					1u,					// deUint32				levelCount;
678 					0u,					// deUint32				baseArrayLayer;
679 					1u					// deUint32				layerCount;
680 				};
681 
682 				// Clear image and transfer layout.
683 				beginCommandBuffer(vk, *cmdBuffer);
684 					vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
685 					vk.cmdClearDepthStencilImage(*cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColorDepth.depthStencil, 1, &clearRange);
686 					vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
687 				endCommandBuffer(vk, *cmdBuffer);
688 
689 				submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
690 			}
691 		}
692 	}
693 
694 	// Create render pass when dynamic_rendering is not tested
695 	if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
696 		m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, testParams);
697 	else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
698 		m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
699 
700 	// Create framebuffer
701 	if (testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
702 	{
703 		std::vector<VkImageView>		imageViews;
704 
705 		for (auto& movePtr : m_colorAttachmentViews)
706 			imageViews.push_back(movePtr.get());
707 
708 		if (hasDepthStencil(m_testParams.depthStencilType))
709 			imageViews.push_back(m_depthAttachmentView.get());
710 
711 		const VkFramebufferCreateInfo	framebufferParams	=
712 		{
713 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
714 			DE_NULL,											// const void*				pNext;
715 			0u,													// VkFramebufferCreateFlags	flags;
716 			*m_renderPass,										// VkRenderPass				renderPass;
717 			static_cast<deUint32>(imageViews.size()),			// deUint32					attachmentCount;
718 			(imageViews.empty() ? DE_NULL : imageViews.data()),	// const VkImageView*		pAttachments;
719 			kImageWidth,										// deUint32					width;
720 			kImageHeight,										// deUint32					height;
721 			1u													// deUint32					layers;
722 		};
723 
724 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
725 	}
726 
727 	// Create pipeline layout for subpass 0.
728 	{
729 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams	=
730 		{
731 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
732 			DE_NULL,												// const void*							pNext
733 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
734 			0u,														// deUint32								bindingCount
735 			DE_NULL													// const VkDescriptorSetLayoutBinding*	pBindings
736 		};
737 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
738 
739 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
740 		{
741 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
742 			DE_NULL,											// const void*						pNext;
743 			0u,													// VkPipelineLayoutCreateFlags		flags;
744 			1u,													// deUint32							setLayoutCount;
745 			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts;
746 			0u,													// deUint32							pushConstantRangeCount;
747 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
748 		};
749 
750 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
751 	}
752 
753 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
754 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
755 
756 	// Create pipeline.
757 	{
758 		const std::vector<VkViewport>						viewports						(1, makeViewport(m_renderSize));
759 		const std::vector<VkRect2D>							scissors						(1, makeRect2D(m_renderSize));
760 
761 		const VkPipelineColorBlendAttachmentState			colorBlendAttachmentState		=
762 		{
763 			VK_FALSE,					// VkBool32					blendEnable
764 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
765 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
766 			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
767 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
768 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
769 			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
770 			VK_COLOR_COMPONENT_R_BIT	// VkColorComponentFlags	colorWriteMask
771 			| VK_COLOR_COMPONENT_G_BIT
772 			| VK_COLOR_COMPONENT_B_BIT
773 			| VK_COLOR_COMPONENT_A_BIT
774 		};
775 
776 		std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;
777 		for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
778 			colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
779 
780 		const VkPipelineColorBlendStateCreateInfo			colorBlendStateCreateInfo		=
781 		{
782 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,							// VkStructureType								sType
783 			DE_NULL,																			// const void*									pNext
784 			0u,																					// VkPipelineColorBlendStateCreateFlags			flags
785 			VK_FALSE,																			// VkBool32										logicOpEnable
786 			VK_LOGIC_OP_CLEAR,																	// VkLogicOp									logicOp
787 			static_cast<deUint32>(colorBlendAttachmentStates.size()),							// deUint32										attachmentCount
788 			(colorBlendAttachmentStates.empty() ? DE_NULL : colorBlendAttachmentStates.data()),	// const VkPipelineColorBlendAttachmentState*	pAttachments
789 			{ 0.0f, 0.0f, 0.0f, 0.0f }															// float										blendConstants[4]
790 		};
791 
792 		void* pNext = DE_NULL;
793 #ifndef CTS_USES_VULKANSC
794 		const std::vector<VkFormat> colorAttachmentFormats(testParams.colorUsed.size(), FORMAT_COLOR);
795 		const bool hasDepth = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
796 			m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY;
797 		const bool hasStencil = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
798 			m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY;
799 		VkPipelineRenderingCreateInfoKHR renderingCreateInfo
800 		{
801 			VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
802 			DE_NULL,
803 			0u,
804 			static_cast<deUint32>(colorAttachmentFormats.size()),
805 			colorAttachmentFormats.data(),
806 			(hasDepth ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
807 			(hasStencil ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
808 		};
809 
810 		if (testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
811 			pNext = &renderingCreateInfo;
812 #endif // CTS_USES_VULKANSC
813 
814 		m_graphicsPipeline = makeGraphicsPipeline(vk,									// const DeviceInterface&							vk
815 												  vkDevice,								// const VkDevice									device
816 												  *m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
817 												  *m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
818 												  DE_NULL,								// const VkShaderModule								tessellationControlModule
819 												  DE_NULL,								// const VkShaderModule								tessellationEvalModule
820 												  DE_NULL,								// const VkShaderModule								geometryShaderModule
821 												  *m_fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
822 												  *m_renderPass,						// const VkRenderPass								renderPass
823 												  viewports,							// const std::vector<VkViewport>&					viewports
824 												  scissors,								// const std::vector<VkRect2D>&						scissors
825 												  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
826 												  0u,									// const deUint32									subpass
827 												  0u,									// const deUint32									patchControlPoints
828 												  DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
829 												  DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
830 												  DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
831 												  DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
832 												  &colorBlendStateCreateInfo,			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
833 												  DE_NULL,								// const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfo
834 												  pNext);								// const void*										pNext
835 	}
836 
837 	// Create command pool
838 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
839 
840 	// Create command buffer
841 	if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
842 		createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
843 	else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
844 		createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
845 	else
846 	{
847 #ifndef CTS_USES_VULKANSC
848 		createCommandBufferDynamicRendering(vk, vkDevice);
849 #endif // CTS_USES_VULKANSC
850 	}
851 }
852 
853 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)854 void UnusedClearAttachmentTestInstance::createCommandBuffer (const DeviceInterface&	vk,
855 															 VkDevice				vkDevice)
856 {
857 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
858 
859 	const VkClearRect									clearRect			=
860 	{
861 		{												// VkRect2D		rect;
862 			{ 0, 0, },									//	VkOffset2D	offset;
863 			{ kImageWidth, kImageHeight }				//	VkExtent2D	extent;
864 		},
865 		0u,												// uint32_t		baseArrayLayer;
866 		1u												// uint32_t		layerCount;
867 	};
868 
869 	std::vector<VkClearAttachment> clearAttachments;
870 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
871 	{
872 		const VkClearAttachment clearAttachment = {
873 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
874 			static_cast<deUint32>(i),	// uint32_t				colorAttachment;
875 			m_clearColor				// VkClearValue			clearValue;
876 		};
877 		clearAttachments.push_back(clearAttachment);
878 	}
879 
880 	if (hasDepthStencil(m_testParams.depthStencilType))
881 	{
882 		const VkClearAttachment clearAttachment = {
883 			getClearAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
884 			0u,													// uint32_t				colorAttachment;
885 			m_clearColorDepth									// VkClearValue			clearValue;
886 		};
887 		clearAttachments.push_back(clearAttachment);
888 	}
889 
890 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
891 
892 	VkRect2D renderArea = makeRect2D(m_renderSize);
893 
894 	const VkRenderPassBeginInfo renderPassBeginInfo
895 	{
896 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
897 		DE_NULL,									// const void*			pNext;
898 		*m_renderPass,								// VkRenderPass			renderPass;
899 		*m_framebuffer,								// VkFramebuffer		framebuffer;
900 		renderArea,									// VkRect2D				renderArea;
901 		0u,											// uint32_t				clearValueCount;
902 		DE_NULL										// const VkClearValue*	pClearValues;
903 	};
904 
905 	const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
906 	RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
907 
908 	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
909 	if (!clearAttachments.empty())
910 	{
911 		vk.cmdClearAttachments(*m_cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
912 	}
913 
914 	const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
915 	RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
916 
917 	endCommandBuffer(vk, *m_cmdBuffer);
918 }
919 
920 #ifndef CTS_USES_VULKANSC
createCommandBufferDynamicRendering(const DeviceInterface & vk,VkDevice vkDevice)921 void UnusedClearAttachmentTestInstance::createCommandBufferDynamicRendering(const DeviceInterface& vk, VkDevice vkDevice)
922 {
923 	const VkClearRect clearRect
924 	{
925 		{														// VkRect2D		rect;
926 			{ 0, 0, },											//	VkOffset2D	offset;
927 			{ kImageWidth, kImageHeight }						//	VkExtent2D	extent;
928 		},
929 		0u,														// uint32_t		baseArrayLayer;
930 		1u														// uint32_t		layerCount;
931 	};
932 
933 	std::vector<VkClearAttachment> clearAttachments;
934 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
935 	{
936 		const VkClearAttachment clearAttachment = {
937 			VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags	aspectMask;
938 			static_cast<deUint32>(i),							// uint32_t				colorAttachment;
939 			m_clearColor										// VkClearValue			clearValue;
940 		};
941 		clearAttachments.push_back(clearAttachment);
942 	}
943 
944 	if (m_testParams.depthStencilUsed)
945 	{
946 		const VkClearAttachment clearAttachment = {
947 			getClearAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
948 			0u,													// uint32_t				colorAttachment;
949 			m_clearColorDepth									// VkClearValue			clearValue;
950 		};
951 		clearAttachments.push_back(clearAttachment);
952 	}
953 
954 	VkRect2D renderArea = makeRect2D(m_renderSize);
955 	std::vector<VkRenderingAttachmentInfoKHR> colorAttachments;
956 	for (size_t i = 0; i < m_colorAttachmentViews.size() ; ++i)
957 	{
958 		colorAttachments.push_back({
959 			VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,					// VkStructureType						sType;
960 			DE_NULL,															// const void*							pNext;
961 			(m_testParams.colorUsed[i]) ? *m_colorAttachmentViews[i] : 0,		// VkImageView							imageView;
962 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,							// VkImageLayout						imageLayout;
963 			VK_RESOLVE_MODE_NONE,												// VkResolveModeFlagBits				resolveMode;
964 			DE_NULL,															// VkImageView							resolveImageView;
965 			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout						resolveImageLayout;
966 			VK_ATTACHMENT_LOAD_OP_LOAD,											// VkAttachmentLoadOp					loadOp;
967 			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp					storeOp;
968 			m_clearColor														// VkClearValue							clearValue;
969 		});
970 	}
971 
972 	VkRenderingAttachmentInfoKHR depthAttachment
973 	{
974 		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,						// VkStructureType						sType;
975 		DE_NULL,																// const void*							pNext;
976 		(m_testParams.depthStencilUsed) ? *m_depthAttachmentView : 0,			// VkImageView							imageView;
977 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,						// VkImageLayout						imageLayout;
978 		VK_RESOLVE_MODE_NONE,													// VkResolveModeFlagBits				resolveMode;
979 		DE_NULL,																// VkImageView							resolveImageView;
980 		VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout						resolveImageLayout;
981 		VK_ATTACHMENT_LOAD_OP_LOAD,												// VkAttachmentLoadOp					loadOp;
982 		VK_ATTACHMENT_STORE_OP_STORE,											// VkAttachmentStoreOp					storeOp;
983 		m_clearColorDepth														// VkClearValue							clearValue;
984 	};
985 
986 	const bool hasDepth		= (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
987 							  m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY) && m_testParams.depthStencilUsed;
988 	const bool hasStencil	= (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
989 							  m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY) && m_testParams.depthStencilUsed;
990 
991 	std::vector<VkFormat> colorAttachmentFormats(m_testParams.colorUsed.size(), VK_FORMAT_UNDEFINED);
992 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
993 		if (m_testParams.colorUsed[i])
994 			colorAttachmentFormats[i] = FORMAT_COLOR;
995 
996 	VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
997 	{
998 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,		// VkStructureType					sType;
999 		DE_NULL,																// const void*						pNext;
1000 		0u,																		// VkRenderingFlagsKHR				flags;
1001 		0u,																		// uint32_t							viewMask;
1002 		static_cast<deUint32>(colorAttachmentFormats.size()),					// uint32_t							colorAttachmentCount;
1003 		colorAttachmentFormats.data(),											// const VkFormat*					pColorAttachmentFormats;
1004 		hasDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							depthAttachmentFormat;
1005 		hasStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							stencilAttachmentFormat;
1006 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			rasterizationSamples;
1007 	};
1008 
1009 	const VkCommandBufferInheritanceInfo	bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
1010 	VkCommandBufferBeginInfo				commandBufBeginParams
1011 	{
1012 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
1013 		DE_NULL,																// const void*						pNext;
1014 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,							// VkCommandBufferUsageFlags		flags;
1015 		&bufferInheritanceInfo
1016 	};
1017 
1018 	VkRenderingInfoKHR renderingInfo
1019 	{
1020 		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
1021 		DE_NULL,
1022 		0u,																		// VkRenderingFlagsKHR					flags;
1023 		renderArea,																// VkRect2D								renderArea;
1024 		1u,																		// deUint32								layerCount;
1025 		0u,																		// deUint32								viewMask;
1026 		static_cast<deUint32>(colorAttachments.size()),							// deUint32								colorAttachmentCount;
1027 		colorAttachments.empty() ? DE_NULL : colorAttachments.data(),			// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
1028 		hasDepth ? &depthAttachment : DE_NULL,									// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
1029 		hasStencil ? &depthAttachment : DE_NULL,								// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
1030 	};
1031 
1032 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1033 
1034 	if (m_testParams.groupParams->useSecondaryCmdBuffer)
1035 	{
1036 		m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1037 
1038 		// record secondary command buffer
1039 		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1040 		{
1041 			inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1042 			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1043 			vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
1044 		}
1045 		else
1046 		{
1047 			commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1048 			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1049 		}
1050 
1051 		vk.cmdBindPipeline(*m_secCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1052 		if (!clearAttachments.empty())
1053 		{
1054 			vk.cmdClearAttachments(*m_secCmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
1055 		}
1056 
1057 		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1058 			vk.cmdEndRendering(*m_secCmdBuffer);
1059 		endCommandBuffer(vk, *m_secCmdBuffer);
1060 
1061 		// record primary command buffer
1062 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1063 		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1064 		{
1065 			renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1066 			vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1067 		}
1068 		vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
1069 		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1070 			vk.cmdEndRendering(*m_cmdBuffer);
1071 		endCommandBuffer(vk, *m_cmdBuffer);
1072 	}
1073 	else
1074 	{
1075 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1076 		vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1077 
1078 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1079 		if (!clearAttachments.empty())
1080 		{
1081 			vk.cmdClearAttachments(*m_cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
1082 		}
1083 
1084 		vk.cmdEndRendering(*m_cmdBuffer);
1085 		endCommandBuffer(vk, *m_cmdBuffer);
1086 	}
1087 }
1088 #endif // CTS_USES_VULKANSC
1089 
iterate(void)1090 tcu::TestStatus	UnusedClearAttachmentTestInstance::iterate (void)
1091 {
1092 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
1093 	const VkDevice			vkDevice			= m_context.getDevice();
1094 	const VkQueue			queue				= m_context.getUniversalQueue();
1095 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1096 	SimpleAllocator			allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1097 
1098 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1099 
1100 	// Read result images.
1101 	std::vector<de::MovePtr<tcu::TextureLevel>> imagePixels;
1102 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
1103 		imagePixels.emplace_back(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImages[i], FORMAT_COLOR, m_renderSize).release());
1104 
1105 	// Verify pixel colors match.
1106 	for (size_t i = 0; i < imagePixels.size(); ++i)
1107 	{
1108 		const tcu::ConstPixelBufferAccess&	imageAccess		= imagePixels[i]->getAccess();
1109 		const float*						refColor		= (m_testParams.colorUsed[i] ? m_clearColor.color.float32 : m_initialColor.color.float32);
1110 
1111 #ifdef CTS_USES_VULKANSC
1112 		if (m_context.getTestContext().getCommandLine().isSubProcess())
1113 #endif // CTS_USES_VULKANSC
1114 		{
1115 			for (int y = 0; y < imageAccess.getHeight(); ++y)
1116 			for (int x = 0; x < imageAccess.getWidth(); ++x)
1117 			{
1118 				const tcu::Vec4	color = imageAccess.getPixel(x, y);
1119 
1120 				for (deUint32 cpnt = 0; cpnt < 4; ++cpnt)
1121 					if (de::abs(color[cpnt] - refColor[cpnt]) > 0.01f)
1122 					{
1123 						std::ostringstream msg;
1124 
1125 						msg << "Attachment " << i << " with mismatched pixel (" << x << ", " << y << "): expecting pixel value [";
1126 						for (deUint32 j = 0; j < 4; ++j)
1127 							msg << ((j == 0) ? "" : ", ") << refColor[j];
1128 						msg << "] and found [";
1129 						for (deUint32 j = 0; j < 4; ++j)
1130 							msg << ((j == 0) ? "" : ", ") << color[j];
1131 						msg << "]";
1132 
1133 						return tcu::TestStatus::fail(msg.str());
1134 					}
1135 			}
1136 		}
1137 	}
1138 
1139 	if (hasDepthStencil(m_testParams.depthStencilType))
1140 	{
1141 		const bool depthOnly	= isDepthOnly(m_testParams.depthStencilType);
1142 		const bool stencilOnly	= isStencilOnly(m_testParams.depthStencilType);
1143 
1144 		if (!stencilOnly)
1145 		{
1146 			de::MovePtr<tcu::TextureLevel>		depthPixels	= pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize);
1147 			const tcu::ConstPixelBufferAccess&	depthAccess	= depthPixels->getAccess();
1148 			const float							refDepth	= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.depth : m_initialColorDepth.depthStencil.depth);
1149 
1150 #ifdef CTS_USES_VULKANSC
1151 			if (m_context.getTestContext().getCommandLine().isSubProcess())
1152 #endif // CTS_USES_VULKANSC
1153 			{
1154 				for (int y = 0; y < depthAccess.getHeight(); ++y)
1155 				for (int x = 0; x < depthAccess.getWidth(); ++x)
1156 				{
1157 					const float value = depthAccess.getPixDepth(x, y);
1158 					if (de::abs(value - refDepth) > 0.001f)
1159 					{
1160 						std::ostringstream msg;
1161 
1162 						msg << "Depth/stencil attachment with mismatched depth value at pixel ("
1163 							<< x << ", " << y << "): expected value " << refDepth << " and found " << value;
1164 						return tcu::TestStatus::fail(msg.str());
1165 					}
1166 				}
1167 			}
1168 		}
1169 
1170 		if (!depthOnly)
1171 		{
1172 			// Note read*Attachment leaves the attachment in the VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout, so the current layout
1173 			// depends on if we have previously read the depth aspect or not.
1174 			const VkImageLayout					currentLayout	= (stencilOnly ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1175 			de::MovePtr<tcu::TextureLevel>		stencilPixels	= pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize, currentLayout);
1176 			const tcu::ConstPixelBufferAccess&	stencilAccess	= stencilPixels->getAccess();
1177 			const deUint32						refStencil		= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.stencil : m_initialColorDepth.depthStencil.stencil);
1178 
1179 #ifdef CTS_USES_VULKANSC
1180 			if (m_context.getTestContext().getCommandLine().isSubProcess())
1181 #endif // CTS_USES_VULKANSC
1182 			{
1183 				for (int y = 0; y < stencilAccess.getHeight(); ++y)
1184 				for (int x = 0; x < stencilAccess.getWidth(); ++x)
1185 				{
1186 					const int value = stencilAccess.getPixStencil(x, y);
1187 					if (value < 0 || static_cast<deUint32>(value) != refStencil)
1188 					{
1189 						std::ostringstream msg;
1190 
1191 						msg << "Depth/stencil attachment with mismatched stencil value at pixel ("
1192 							<< x << ", " << y << "): expected value " << refStencil << " and found " << value;
1193 						return tcu::TestStatus::fail(msg.str());
1194 					}
1195 				}
1196 			}
1197 		}
1198 	}
1199 
1200 	return tcu::TestStatus::pass("Pass");
1201 }
1202 
1203 
1204 using CallbackFunction = std::function<void(const std::vector<deBool>&)>;
1205 
runCallbackOnCombination(std::vector<deBool> & array,size_t current_index,CallbackFunction callback)1206 void runCallbackOnCombination(std::vector<deBool>& array, size_t current_index, CallbackFunction callback)
1207 {
1208 	DE_ASSERT(current_index < array.size());
1209 	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
1210 	{
1211 		array[current_index] = DE_BOOL_VALUES[i];
1212 		if (current_index == array.size() - 1)
1213 			callback(array);
1214 		else
1215 			runCallbackOnCombination(array, current_index + 1, callback);
1216 	}
1217 }
1218 
runCallbackOnCombination(std::vector<deBool> & array,CallbackFunction callback)1219 void runCallbackOnCombination(std::vector<deBool>& array, CallbackFunction callback)
1220 {
1221 	runCallbackOnCombination(array, 0, callback);
1222 }
1223 
getUsed(deBool value)1224 std::string getUsed(deBool value)
1225 {
1226 	return (value ? "used" : "unused");
1227 }
1228 
getCombName(const std::vector<deBool> & array)1229 std::string getCombName(const std::vector<deBool>& array)
1230 {
1231 	std::ostringstream name;
1232 	for (size_t i = 0; i < array.size(); ++i)
1233 		name << ((i == 0)? "" : "_") << "color" << getUsed(array[i]);
1234 	return name.str();
1235 }
1236 
1237 } // anonymous
1238 
1239 
createRenderPassUnusedClearAttachmentTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1240 tcu::TestCaseGroup* createRenderPassUnusedClearAttachmentTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
1241 {
1242 	de::MovePtr<tcu::TestCaseGroup>	testGroup (new tcu::TestCaseGroup(testCtx, "unused_clear_attachments", "Unused attachments with vkCmdClearAttachments"));
1243 
1244 	for (int depthStencilType = 0; depthStencilType < DEPTH_STENCIL_MAX_ENUM; ++depthStencilType)
1245 	{
1246 		const DepthStencilType	dsType		= static_cast<DepthStencilType>(depthStencilType);
1247 		const auto				dsFormats	= getFormats(dsType);
1248 
1249 		for (const auto dsFormat : dsFormats)
1250 		{
1251 			for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
1252 			{
1253 				const deBool			depthStencilUse	= DE_BOOL_VALUES[i];
1254 
1255 				if (groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING
1256 					&& dsType != DEPTH_STENCIL_NONE && !depthStencilUse
1257 					&& groupParams->useSecondaryCmdBuffer
1258 					&& !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1259 				{
1260 					// In dynamic rendering, we cannot have D/S format set for attachment in secondary command buffer,
1261 					// while having no attachment in rendering info in primary command buffer.
1262 					//
1263 					// Spec:
1264 					// If vkCmdExecuteCommands is being called within a render pass instance begun with vkCmdBeginRendering and
1265 					// the VkRenderingInfo::pDepthAttachment->imageView parameter to vkCmdBeginRendering was VK_NULL_HANDLE,
1266 					// the value of the depthAttachmentFormat member of the VkCommandBufferInheritanceRenderingInfo structure included
1267 					// in the pNext chain of VkCommandBufferBeginInfo::pInheritanceInfo used to begin recording each element of
1268 					// pCommandBuffers must be VK_FORMAT_UNDEFINED
1269 					continue;
1270 				}
1271 
1272 				const std::string		dsCase			= depthStencilTypeName(dsType, dsFormat);
1273 				std::vector<TestParams>	testTypes;
1274 
1275 				if (hasDepthStencil(dsType))
1276 					testTypes.emplace_back(0, dsType, depthStencilUse, dsFormat, groupParams);							// No color attachments.
1277 				testTypes.emplace_back(1, dsType, depthStencilUse, dsFormat, groupParams);								// Single color attachment.
1278 				testTypes.emplace_back(COLOR_ATTACHMENTS_NUMBER, dsType, depthStencilUse, dsFormat, groupParams);		// Multiple color attachments.
1279 
1280 				for (auto& params : testTypes)
1281 				{
1282 					if (!params.colorUsed.empty())
1283 					{
1284 						runCallbackOnCombination(params.colorUsed, [&](const std::vector<deBool>& array) {
1285 							std::string name = getCombName(array) + "_" + dsCase;
1286 							if (hasDepthStencil(dsType))
1287 								name += std::string("_") + getUsed(depthStencilUse);
1288 							testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, "", params));
1289 						});
1290 					}
1291 					else
1292 					{
1293 						std::string name = dsCase + "_" + getUsed(depthStencilUse);
1294 						testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, "", params));
1295 					}
1296 
1297 				}
1298 
1299 				if (!hasDepthStencil(dsType))
1300 					break;
1301 			}
1302 		}
1303 	}
1304 
1305 	return testGroup.release();
1306 }
1307 
1308 } // renderpass
1309 } // vkt
1310