• 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::__anonc47934290111::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 TestParams & testParams)227 										UnusedClearAttachmentTest	(tcu::TestContext&	testContext,
228 																	 const std::string&	name,
229 																	 const TestParams&	testParams)
230 											: vkt::TestCase(testContext, name)
231 											, m_testParams(testParams)
232 											{}
~UnusedClearAttachmentTest(void)233 	virtual								~UnusedClearAttachmentTest	(void) {}
234 	virtual void						initPrograms				(SourceCollections&	sourceCollections) const;
235 	virtual TestInstance*				createInstance				(Context&			context) const;
236 	virtual void						checkSupport				(Context&			context) const;
237 private:
238 	const TestParams					m_testParams;
239 };
240 
checkFormatSupported(Context & context,VkFormat format,VkImageUsageFlags usage)241 void checkFormatSupported(Context& context, VkFormat format, VkImageUsageFlags usage)
242 {
243 	VkResult					result;
244 	VkImageFormatProperties		properties;
245 
246 	result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
247 		context.getPhysicalDevice(), format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
248 
249 	if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
250 	{
251 		std::ostringstream msg;
252 		msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
253 		TCU_THROW(NotSupportedError, msg.str());
254 	}
255 
256 	VK_CHECK(result);
257 }
258 
checkSupport(Context & context) const259 void UnusedClearAttachmentTest::checkSupport (Context& context) const
260 {
261 	// Check for renderpass2 extension if used
262 	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
263 		context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
264 
265 	// Check for dynamic_rendering extension if used
266 	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
267 		context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
268 
269 	// Check support for the needed color, depth and stencil formats.
270 	if (!m_testParams.colorUsed.empty())
271 		checkFormatSupported(context, FORMAT_COLOR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
272 
273 	if (hasDepthStencil(m_testParams.depthStencilType))
274 		checkFormatSupported(context, m_testParams.depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
275 }
276 
createInstance(Context & context) const277 TestInstance* UnusedClearAttachmentTest::createInstance (Context& context) const
278 {
279 	return new UnusedClearAttachmentTestInstance(context, m_testParams);
280 }
281 
282 // 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) const283 void UnusedClearAttachmentTest::initPrograms (SourceCollections& sourceCollections) const
284 {
285 	// Vertex shader.
286 	sourceCollections.glslSources.add("vert_shader") << glu::VertexSource(
287 		"#version 450\n"
288 		"precision highp float;\n"
289 		"layout(location = 0) in vec4 position;\n"
290 		"layout(location = 0) out vec4 vtxColor;\n"
291 		"void main (void)\n"
292 		"{\n"
293 		"\tgl_Position = position;\n"
294 		"\tvtxColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
295 		"}\n");
296 
297 	// Fragment shader.
298 	std::ostringstream fragmentSource;
299 
300 	fragmentSource	<< "#version 450\n"
301 					<< "precision highp float;\n"
302 					<< "layout(location = 0) in vec4 vtxColor;\n";
303 
304 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
305 	{
306 		if (m_testParams.colorUsed[i])
307 			fragmentSource << "layout(location = " << i << ") out vec4 fragColor" << i << ";\n";
308 	}
309 
310 	fragmentSource	<< "void main (void)\n"
311 					<< "{\n";
312 
313 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
314 	{
315 		if (m_testParams.colorUsed[i])
316 			fragmentSource << "\tfragColor" << i << " = vtxColor;\n";
317 	}
318 
319 	fragmentSource	<< "}\n";
320 
321 	sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
322 }
323 
324 // Create a render pass for this use case.
325 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,const TestParams testParams)326 Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk,
327 									 VkDevice				vkDevice,
328 									 const TestParams		testParams)
329 {
330 	const VkImageAspectFlags	colorAspectMask					= VK_IMAGE_ASPECT_COLOR_BIT;
331 	const VkImageAspectFlags	dsClearAspectMask				= getClearAspectMask(testParams.depthStencilType);
332 	const bool					isDepthStencil					= hasDepthStencil(testParams.depthStencilType);
333 
334 	// Create attachment descriptions.
335 	const AttachmentDesc		attachmentDescription			(
336 		DE_NULL,									// const void*						pNext
337 		(VkAttachmentDescriptionFlags)0,			// VkAttachmentDescriptionFlags		flags
338 		FORMAT_COLOR,								// VkFormat							format
339 		VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits			samples
340 		VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				loadOp
341 		VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp
342 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,			// VkAttachmentLoadOp				stencilLoadOp
343 		VK_ATTACHMENT_STORE_OP_DONT_CARE,			// VkAttachmentStoreOp				stencilStoreOp
344 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
345 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
346 	);
347 	std::vector<AttachmentDesc>	attachmentDescriptions			(testParams.colorUsed.size(), attachmentDescription);
348 
349 	if (isDepthStencil)
350 	{
351 		const bool					depthOnly		= isDepthOnly(testParams.depthStencilType);
352 		const bool					stencilOnly		= isStencilOnly(testParams.depthStencilType);
353 		const VkAttachmentLoadOp	depthLoadOp		= (stencilOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
354 		const VkAttachmentStoreOp	depthStoreOp	= (stencilOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
355 		const VkAttachmentLoadOp	stencilLoadOp	= (depthOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
356 		const VkAttachmentStoreOp	stencilStoreOp	= (depthOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
357 
358 		attachmentDescriptions.emplace_back(
359 			nullptr,											// const void*						pNext
360 			(VkAttachmentDescriptionFlags)0,					// VkAttachmentDescriptionFlags		flags
361 			testParams.depthStencilFormat,						// VkFormat							format
362 			VK_SAMPLE_COUNT_1_BIT,								// VkSampleCountFlagBits			samples
363 			depthLoadOp,										// VkAttachmentLoadOp				loadOp
364 			depthStoreOp,										// VkAttachmentStoreOp				storeOp
365 			stencilLoadOp,										// VkAttachmentLoadOp				stencilLoadOp
366 			stencilStoreOp,										// VkAttachmentStoreOp				stencilStoreOp
367 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout					initialLayout
368 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL	// VkImageLayout					finalLayout
369 		);
370 	}
371 
372 	// Mark attachments as used or not depending on the test parameters.
373 	std::vector<AttachmentRef>		attachmentReferences;
374 	for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
375 	{
376 		attachmentReferences.push_back(AttachmentRef(
377 			DE_NULL,																		// const void*			pNext
378 			(testParams.colorUsed[i] ? static_cast<deUint32>(i) : VK_ATTACHMENT_UNUSED),	// deUint32				attachment
379 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,										// VkImageLayout		layout
380 			colorAspectMask																	// VkImageAspectFlags	aspectMask
381 		));
382 	}
383 
384 	std::unique_ptr<AttachmentRef>	depthAttachmentRef;
385 	if (isDepthStencil)
386 	{
387 		depthAttachmentRef.reset(new AttachmentRef(
388 			DE_NULL,
389 			(testParams.depthStencilUsed ? static_cast<deUint32>(testParams.colorUsed.size()) : VK_ATTACHMENT_UNUSED),
390 			VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
391 			dsClearAspectMask
392 		));
393 	}
394 
395 	// Create subpass description with the previous color attachment references.
396 	const SubpassDesc			subpassDescription				(
397 		DE_NULL,
398 		(VkSubpassDescriptionFlags)0,											// VkSubpassDescriptionFlags		flags
399 		VK_PIPELINE_BIND_POINT_GRAPHICS,										// VkPipelineBindPoint				pipelineBindPoint
400 		0u,																		// deUint32							viewMask
401 		0u,																		// deUint32							inputAttachmentCount
402 		DE_NULL,																// const VkAttachmentReference*		pInputAttachments
403 		static_cast<deUint32>(attachmentReferences.size()),						// deUint32							colorAttachmentCount
404 		(attachmentReferences.empty() ? DE_NULL : attachmentReferences.data()),	// const VkAttachmentReference*		pColorAttachments
405 		DE_NULL,																// const VkAttachmentReference*		pResolveAttachments
406 		(depthAttachmentRef ? depthAttachmentRef.get() : DE_NULL),				// const VkAttachmentReference*		pDepthStencilAttachment
407 		0u,																		// deUint32							preserveAttachmentCount
408 		DE_NULL																	// const deUint32*					pPreserveAttachments
409 	);
410 
411 	const RenderPassCreateInfo	renderPassInfo					(
412 		DE_NULL,																	// const void*						pNext
413 		(VkRenderPassCreateFlags)0,													// VkRenderPassCreateFlags			flags
414 		static_cast<deUint32>(attachmentDescriptions.size()),						// deUint32							attachmentCount
415 		(attachmentDescriptions.empty() ? DE_NULL : attachmentDescriptions.data()),	// const VkAttachmentDescription*	pAttachments
416 		1u,																			// deUint32							subpassCount
417 		&subpassDescription,														// const VkSubpassDescription*		pSubpasses
418 		0u,																			// deUint32							dependencyCount
419 		DE_NULL,																	// const VkSubpassDependency*		pDependencies
420 		0u,																			// deUint32							correlatedViewMaskCount
421 		DE_NULL																		// const deUint32*					pCorrelatedViewMasks
422 	);
423 
424 	return renderPassInfo.createRenderPass(vk, vkDevice);
425 }
426 
UnusedClearAttachmentTestInstance(Context & context,const TestParams & testParams)427 UnusedClearAttachmentTestInstance::UnusedClearAttachmentTestInstance(Context&			context,
428 																	 const TestParams&	testParams)
429 	: vkt::TestInstance(context)
430 	, m_testParams(testParams)
431 {
432 	// Initial color for all images.
433 	m_initialColor.color.float32[0] = 0.0f;
434 	m_initialColor.color.float32[1] = 0.0f;
435 	m_initialColor.color.float32[2] = 0.0f;
436 	m_initialColor.color.float32[3] = 1.0f;
437 
438 	m_initialColorDepth.depthStencil.depth = 1.0f;
439 	m_initialColorDepth.depthStencil.stencil = 0u;
440 
441 	// Clear color for used attachments.
442 	m_clearColor.color.float32[0] = 1.0f;
443 	m_clearColor.color.float32[1] = 1.0f;
444 	m_clearColor.color.float32[2] = 1.0f;
445 	m_clearColor.color.float32[3] = 1.0f;
446 
447 	m_clearColorDepth.depthStencil.depth = 0.0f;
448 	m_clearColorDepth.depthStencil.stencil = 255u;
449 
450 	const DeviceInterface&		vk						= m_context.getDeviceInterface();
451 	const VkDevice				vkDevice				= m_context.getDevice();
452 	const deUint32				queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
453 	SimpleAllocator				memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
454 	const VkComponentMapping	componentMapping		= { VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY };
455 
456 	// Create color images.
457 	{
458 		const VkImageCreateInfo	colorImageParams =
459 		{
460 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// VkStructureType			sType;
461 			DE_NULL,																// const void*				pNext;
462 			0u,																		// VkImageCreateFlags		flags;
463 			VK_IMAGE_TYPE_2D,														// VkImageType				imageType;
464 			FORMAT_COLOR,															// VkFormat					format;
465 			{ kImageWidth, kImageHeight, 1u },										// VkExtent3D				extent;
466 			1u,																		// deUint32					mipLevels;
467 			1u,																		// deUint32					arrayLayers;
468 			VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits	samples;
469 			VK_IMAGE_TILING_OPTIMAL,												// VkImageTiling			tiling;
470 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
471 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT,									// VkImageUsageFlags		usage;
472 			VK_SHARING_MODE_EXCLUSIVE,												// VkSharingMode			sharingMode;
473 			1u,																		// deUint32					queueFamilyIndexCount;
474 			&queueFamilyIndex,														// const deUint32*			pQueueFamilyIndices;
475 			VK_IMAGE_LAYOUT_UNDEFINED												// VkImageLayout			initialLayout;
476 		};
477 
478 		const VkImageCreateInfo depthImageParams =
479 		{
480 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,											// VkStructureType			sType;
481 			DE_NULL,																		// const void*				pNext;
482 			0u,																				// VkImageCreateFlags		flags;
483 			VK_IMAGE_TYPE_2D,																// VkImageType				imageType;
484 			m_testParams.depthStencilFormat,												// VkFormat					format;
485 			{ kImageWidth, kImageHeight, 1u },												// VkExtent3D				extent;
486 			1u,																				// deUint32					mipLevels;
487 			1u,																				// deUint32					arrayLayers;
488 			VK_SAMPLE_COUNT_1_BIT,															// VkSampleCountFlagBits	samples;
489 			VK_IMAGE_TILING_OPTIMAL,														// VkImageTiling			tiling;
490 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
491 				| VK_IMAGE_USAGE_TRANSFER_DST_BIT,											// VkImageUsageFlags		usage;
492 			VK_SHARING_MODE_EXCLUSIVE,														// VkSharingMode			sharingMode;
493 			1u,																				// deUint32					queueFamilyIndexCount;
494 			&queueFamilyIndex,																// const deUint32*			pQueueFamilyIndices;
495 			VK_IMAGE_LAYOUT_UNDEFINED														// VkImageLayout			initialLayout;
496 		};
497 
498 		for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
499 		{
500 			// Create, allocate and bind image memory.
501 			m_colorImages.emplace_back(createImage(vk, vkDevice, &colorImageParams));
502 			m_colorImageAllocs.emplace_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImages.back()), MemoryRequirement::Any));
503 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImages.back(), m_colorImageAllocs.back()->getMemory(), m_colorImageAllocs.back()->getOffset()));
504 
505 			// Create image view.
506 			{
507 				const VkImageViewCreateInfo colorAttachmentViewParams =
508 				{
509 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
510 					DE_NULL,											// const void*				pNext;
511 					0u,													// VkImageViewCreateFlags	flags;
512 					*m_colorImages.back(),								// VkImage					image;
513 					VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
514 					FORMAT_COLOR,										// VkFormat					format;
515 					componentMapping,									// VkChannelMapping			channels;
516 					{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
517 				};
518 
519 				m_colorAttachmentViews.emplace_back(createImageView(vk, vkDevice, &colorAttachmentViewParams));
520 			}
521 
522 			// Clear image and leave it prepared to be used as a color attachment.
523 			{
524 				const VkImageAspectFlags		aspectMask	= VK_IMAGE_ASPECT_COLOR_BIT;
525 				Move<VkCommandPool>				cmdPool;
526 				Move<VkCommandBuffer>			cmdBuffer;
527 
528 				// Create command pool and buffer
529 				cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
530 				cmdBuffer	= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
531 
532 				// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
533 				const VkImageMemoryBarrier preImageBarrier =
534 				{
535 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
536 					DE_NULL,								// const void*				pNext;
537 					0u,										// VkAccessFlags			srcAccessMask;
538 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
539 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
540 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
541 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
542 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
543 					*m_colorImages.back(),					// VkImage					image;
544 					{										// VkImageSubresourceRange	subresourceRange;
545 						aspectMask,							// VkImageAspect			aspect;
546 						0u,									// deUint32					baseMipLevel;
547 						1u,									// deUint32					mipLevels;
548 						0u,									// deUint32					baseArraySlice;
549 						1u									// deUint32					arraySize;
550 					}
551 				};
552 
553 				// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
554 				const VkImageMemoryBarrier postImageBarrier =
555 				{
556 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
557 					DE_NULL,									// const void*				pNext;
558 					VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
559 					VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
560 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
561 					VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
562 					VK_QUEUE_FAMILY_IGNORED,					// deUint32					srcQueueFamilyIndex;
563 					VK_QUEUE_FAMILY_IGNORED,					// deUint32					dstQueueFamilyIndex;
564 					*m_colorImages.back(),						// VkImage					image;
565 					{											// VkImageSubresourceRange	subresourceRange;
566 						aspectMask,								// VkImageAspect			aspect;
567 						0u,										// deUint32					baseMipLevel;
568 						1u,										// deUint32					mipLevels;
569 						0u,										// deUint32					baseArraySlice;
570 						1u										// deUint32					arraySize;
571 					}
572 				};
573 
574 				const VkImageSubresourceRange clearRange	=
575 				{
576 					aspectMask,	// VkImageAspectFlags	aspectMask;
577 					0u,			// deUint32				baseMipLevel;
578 					1u,			// deUint32				levelCount;
579 					0u,			// deUint32				baseArrayLayer;
580 					1u			// deUint32				layerCount;
581 				};
582 
583 				// Clear image and transfer layout.
584 				beginCommandBuffer(vk, *cmdBuffer);
585 					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);
586 					vk.cmdClearColorImage(*cmdBuffer, *m_colorImages.back(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColor.color, 1, &clearRange);
587 					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);
588 				endCommandBuffer(vk, *cmdBuffer);
589 
590 				submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
591 			}
592 		}
593 
594 		if (hasDepthStencil(m_testParams.depthStencilType))
595 		{
596 			const VkImageAspectFlags clearAspectMask	= getClearAspectMask(m_testParams.depthStencilType);
597 			const VkImageAspectFlags formatAspectMask	= getFormatAspectMask(m_testParams.depthStencilFormat);
598 
599 			// Create, allocate and bind image memory.
600 			m_depthImage = createImage(vk, vkDevice, &depthImageParams);
601 			m_depthImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
602 			VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(), m_depthImageAlloc->getOffset()));
603 
604 			// Create image view.
605 			{
606 				const VkImageViewCreateInfo depthAttachmentViewParams =
607 				{
608 					VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
609 					DE_NULL,									// const void*				pNext;
610 					0u,											// VkImageViewCreateFlags	flags;
611 					*m_depthImage,								// VkImage					image;
612 					VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
613 					m_testParams.depthStencilFormat,			// VkFormat					format;
614 					componentMapping,							// VkChannelMapping			channels;
615 					{ clearAspectMask, 0u, 1u, 0u, 1u }			// VkImageSubresourceRange	subresourceRange;
616 				};
617 
618 				m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
619 			}
620 
621 			// Clear image and leave it prepared to be used as a depth/stencil attachment.
622 			{
623 				Move<VkCommandPool>				cmdPool;
624 				Move<VkCommandBuffer>			cmdBuffer;
625 
626 				// Create command pool and buffer
627 				cmdPool		= createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
628 				cmdBuffer	= allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
629 
630 				// From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
631 				const VkImageMemoryBarrier		preImageBarrier =
632 				{
633 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,	// VkStructureType			sType;
634 					DE_NULL,								// const void*				pNext;
635 					0u,										// VkAccessFlags			srcAccessMask;
636 					VK_ACCESS_TRANSFER_WRITE_BIT,			// VkAccessFlags			dstAccessMask;
637 					VK_IMAGE_LAYOUT_UNDEFINED,				// VkImageLayout			oldLayout;
638 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,	// VkImageLayout			newLayout;
639 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					srcQueueFamilyIndex;
640 					VK_QUEUE_FAMILY_IGNORED,				// deUint32					dstQueueFamilyIndex;
641 					*m_depthImage,							// VkImage					image;
642 					{										// VkImageSubresourceRange	subresourceRange;
643 						formatAspectMask,					// VkImageAspect			aspect;
644 						0u,									// deUint32					baseMipLevel;
645 						1u,									// deUint32					mipLevels;
646 						0u,									// deUint32					baseArraySlice;
647 						1u									// deUint32					arraySize;
648 					}
649 				};
650 
651 				// From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.
652 				const VkImageMemoryBarrier		postImageBarrier =
653 				{
654 					VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,				// VkStructureType			sType;
655 					DE_NULL,											// const void*				pNext;
656 					VK_ACCESS_TRANSFER_WRITE_BIT,						// VkAccessFlags			srcAccessMask;
657 					VK_ACCESS_SHADER_READ_BIT,							// VkAccessFlags			dstAccessMask;
658 					VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,				// VkImageLayout			oldLayout;
659 					VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout			newLayout;
660 					VK_QUEUE_FAMILY_IGNORED,							// deUint32					srcQueueFamilyIndex;
661 					VK_QUEUE_FAMILY_IGNORED,							// deUint32					dstQueueFamilyIndex;
662 					*m_depthImage,										// VkImage					image;
663 					{													// VkImageSubresourceRange	subresourceRange;
664 						formatAspectMask,								// VkImageAspect			aspect;
665 						0u,												// deUint32					baseMipLevel;
666 						1u,												// deUint32					mipLevels;
667 						0u,												// deUint32					baseArraySlice;
668 						1u												// deUint32					arraySize;
669 					}
670 				};
671 
672 				const VkImageSubresourceRange	clearRange	=
673 				{
674 					clearAspectMask,	// VkImageAspectFlags	aspectMask;
675 					0u,					// deUint32				baseMipLevel;
676 					1u,					// deUint32				levelCount;
677 					0u,					// deUint32				baseArrayLayer;
678 					1u					// deUint32				layerCount;
679 				};
680 
681 				// Clear image and transfer layout.
682 				beginCommandBuffer(vk, *cmdBuffer);
683 					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);
684 					vk.cmdClearDepthStencilImage(*cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &m_initialColorDepth.depthStencil, 1, &clearRange);
685 					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);
686 				endCommandBuffer(vk, *cmdBuffer);
687 
688 				submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
689 			}
690 		}
691 	}
692 
693 	// Create render pass when dynamic_rendering is not tested
694 	if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
695 		m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, testParams);
696 	else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
697 		m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
698 
699 	// Create framebuffer
700 	if (testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
701 	{
702 		std::vector<VkImageView>		imageViews;
703 
704 		for (auto& movePtr : m_colorAttachmentViews)
705 			imageViews.push_back(movePtr.get());
706 
707 		if (hasDepthStencil(m_testParams.depthStencilType))
708 			imageViews.push_back(m_depthAttachmentView.get());
709 
710 		const VkFramebufferCreateInfo	framebufferParams	=
711 		{
712 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
713 			DE_NULL,											// const void*				pNext;
714 			0u,													// VkFramebufferCreateFlags	flags;
715 			*m_renderPass,										// VkRenderPass				renderPass;
716 			static_cast<deUint32>(imageViews.size()),			// deUint32					attachmentCount;
717 			(imageViews.empty() ? DE_NULL : imageViews.data()),	// const VkImageView*		pAttachments;
718 			kImageWidth,										// deUint32					width;
719 			kImageHeight,										// deUint32					height;
720 			1u													// deUint32					layers;
721 		};
722 
723 		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
724 	}
725 
726 	// Create pipeline layout for subpass 0.
727 	{
728 		const VkDescriptorSetLayoutCreateInfo	descriptorSetLayoutParams	=
729 		{
730 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,	// VkStructureType						sType
731 			DE_NULL,												// const void*							pNext
732 			0u,														// VkDescriptorSetLayoutCreateFlags		flags
733 			0u,														// deUint32								bindingCount
734 			DE_NULL													// const VkDescriptorSetLayoutBinding*	pBindings
735 		};
736 		m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
737 
738 		const VkPipelineLayoutCreateInfo		pipelineLayoutParams		=
739 		{
740 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType					sType;
741 			DE_NULL,											// const void*						pNext;
742 			0u,													// VkPipelineLayoutCreateFlags		flags;
743 			1u,													// deUint32							setLayoutCount;
744 			&m_descriptorSetLayout.get(),						// const VkDescriptorSetLayout*		pSetLayouts;
745 			0u,													// deUint32							pushConstantRangeCount;
746 			DE_NULL												// const VkPushConstantRange*		pPushConstantRanges;
747 		};
748 
749 		m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
750 	}
751 
752 	m_vertexShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
753 	m_fragmentShaderModule	= createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
754 
755 	// Create pipeline.
756 	{
757 		const std::vector<VkViewport>						viewports						(1, makeViewport(m_renderSize));
758 		const std::vector<VkRect2D>							scissors						(1, makeRect2D(m_renderSize));
759 
760 		const VkPipelineColorBlendAttachmentState			colorBlendAttachmentState		=
761 		{
762 			VK_FALSE,					// VkBool32					blendEnable
763 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcColorBlendFactor
764 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstColorBlendFactor
765 			VK_BLEND_OP_ADD,			// VkBlendOp				colorBlendOp
766 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			srcAlphaBlendFactor
767 			VK_BLEND_FACTOR_ZERO,		// VkBlendFactor			dstAlphaBlendFactor
768 			VK_BLEND_OP_ADD,			// VkBlendOp				alphaBlendOp
769 			VK_COLOR_COMPONENT_R_BIT	// VkColorComponentFlags	colorWriteMask
770 			| VK_COLOR_COMPONENT_G_BIT
771 			| VK_COLOR_COMPONENT_B_BIT
772 			| VK_COLOR_COMPONENT_A_BIT
773 		};
774 
775 		std::vector<VkPipelineColorBlendAttachmentState>	colorBlendAttachmentStates;
776 		for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
777 			colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
778 
779 		const VkPipelineColorBlendStateCreateInfo			colorBlendStateCreateInfo		=
780 		{
781 			VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,							// VkStructureType								sType
782 			DE_NULL,																			// const void*									pNext
783 			0u,																					// VkPipelineColorBlendStateCreateFlags			flags
784 			VK_FALSE,																			// VkBool32										logicOpEnable
785 			VK_LOGIC_OP_CLEAR,																	// VkLogicOp									logicOp
786 			static_cast<deUint32>(colorBlendAttachmentStates.size()),							// deUint32										attachmentCount
787 			(colorBlendAttachmentStates.empty() ? DE_NULL : colorBlendAttachmentStates.data()),	// const VkPipelineColorBlendAttachmentState*	pAttachments
788 			{ 0.0f, 0.0f, 0.0f, 0.0f }															// float										blendConstants[4]
789 		};
790 
791 		void* pNext = DE_NULL;
792 #ifndef CTS_USES_VULKANSC
793 		const std::vector<VkFormat> colorAttachmentFormats(testParams.colorUsed.size(), FORMAT_COLOR);
794 		const bool hasDepth = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
795 			m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY;
796 		const bool hasStencil = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
797 			m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY;
798 		VkPipelineRenderingCreateInfoKHR renderingCreateInfo
799 		{
800 			VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
801 			DE_NULL,
802 			0u,
803 			static_cast<deUint32>(colorAttachmentFormats.size()),
804 			colorAttachmentFormats.data(),
805 			(hasDepth ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
806 			(hasStencil ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
807 		};
808 
809 		if (testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
810 			pNext = &renderingCreateInfo;
811 #endif // CTS_USES_VULKANSC
812 
813 		m_graphicsPipeline = makeGraphicsPipeline(vk,									// const DeviceInterface&							vk
814 												  vkDevice,								// const VkDevice									device
815 												  *m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
816 												  *m_vertexShaderModule,				// const VkShaderModule								vertexShaderModule
817 												  DE_NULL,								// const VkShaderModule								tessellationControlModule
818 												  DE_NULL,								// const VkShaderModule								tessellationEvalModule
819 												  DE_NULL,								// const VkShaderModule								geometryShaderModule
820 												  *m_fragmentShaderModule,				// const VkShaderModule								fragmentShaderModule
821 												  *m_renderPass,						// const VkRenderPass								renderPass
822 												  viewports,							// const std::vector<VkViewport>&					viewports
823 												  scissors,								// const std::vector<VkRect2D>&						scissors
824 												  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
825 												  0u,									// const deUint32									subpass
826 												  0u,									// const deUint32									patchControlPoints
827 												  DE_NULL,								// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
828 												  DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
829 												  DE_NULL,								// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
830 												  DE_NULL,								// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
831 												  &colorBlendStateCreateInfo,			// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
832 												  DE_NULL,								// const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfo
833 												  pNext);								// const void*										pNext
834 	}
835 
836 	// Create command pool
837 	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
838 
839 	// Create command buffer
840 	if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
841 		createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
842 	else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
843 		createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
844 	else
845 	{
846 #ifndef CTS_USES_VULKANSC
847 		createCommandBufferDynamicRendering(vk, vkDevice);
848 #endif // CTS_USES_VULKANSC
849 	}
850 }
851 
852 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)853 void UnusedClearAttachmentTestInstance::createCommandBuffer (const DeviceInterface&	vk,
854 															 VkDevice				vkDevice)
855 {
856 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
857 
858 	const VkClearRect									clearRect			=
859 	{
860 		{												// VkRect2D		rect;
861 			{ 0, 0, },									//	VkOffset2D	offset;
862 			{ kImageWidth, kImageHeight }				//	VkExtent2D	extent;
863 		},
864 		0u,												// uint32_t		baseArrayLayer;
865 		1u												// uint32_t		layerCount;
866 	};
867 
868 	std::vector<VkClearAttachment> clearAttachments;
869 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
870 	{
871 		const VkClearAttachment clearAttachment = {
872 			VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
873 			static_cast<deUint32>(i),	// uint32_t				colorAttachment;
874 			m_clearColor				// VkClearValue			clearValue;
875 		};
876 		clearAttachments.push_back(clearAttachment);
877 	}
878 
879 	if (hasDepthStencil(m_testParams.depthStencilType))
880 	{
881 		const VkClearAttachment clearAttachment = {
882 			getClearAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
883 			0u,													// uint32_t				colorAttachment;
884 			m_clearColorDepth									// VkClearValue			clearValue;
885 		};
886 		clearAttachments.push_back(clearAttachment);
887 	}
888 
889 	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
890 
891 	VkRect2D renderArea = makeRect2D(m_renderSize);
892 
893 	const VkRenderPassBeginInfo renderPassBeginInfo
894 	{
895 		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType;
896 		DE_NULL,									// const void*			pNext;
897 		*m_renderPass,								// VkRenderPass			renderPass;
898 		*m_framebuffer,								// VkFramebuffer		framebuffer;
899 		renderArea,									// VkRect2D				renderArea;
900 		0u,											// uint32_t				clearValueCount;
901 		DE_NULL										// const VkClearValue*	pClearValues;
902 	};
903 
904 	const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
905 	RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
906 
907 	vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
908 	if (!clearAttachments.empty())
909 	{
910 		vk.cmdClearAttachments(*m_cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
911 	}
912 
913 	const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
914 	RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
915 
916 	endCommandBuffer(vk, *m_cmdBuffer);
917 }
918 
919 #ifndef CTS_USES_VULKANSC
createCommandBufferDynamicRendering(const DeviceInterface & vk,VkDevice vkDevice)920 void UnusedClearAttachmentTestInstance::createCommandBufferDynamicRendering(const DeviceInterface& vk, VkDevice vkDevice)
921 {
922 	const VkClearRect clearRect
923 	{
924 		{														// VkRect2D		rect;
925 			{ 0, 0, },											//	VkOffset2D	offset;
926 			{ kImageWidth, kImageHeight }						//	VkExtent2D	extent;
927 		},
928 		0u,														// uint32_t		baseArrayLayer;
929 		1u														// uint32_t		layerCount;
930 	};
931 
932 	std::vector<VkClearAttachment> clearAttachments;
933 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
934 	{
935 		const VkClearAttachment clearAttachment = {
936 			VK_IMAGE_ASPECT_COLOR_BIT,							// VkImageAspectFlags	aspectMask;
937 			static_cast<deUint32>(i),							// uint32_t				colorAttachment;
938 			m_clearColor										// VkClearValue			clearValue;
939 		};
940 		clearAttachments.push_back(clearAttachment);
941 	}
942 
943 	if (m_testParams.depthStencilUsed)
944 	{
945 		const VkClearAttachment clearAttachment = {
946 			getClearAspectMask(m_testParams.depthStencilType),	// VkImageAspectFlags	aspectMask;
947 			0u,													// uint32_t				colorAttachment;
948 			m_clearColorDepth									// VkClearValue			clearValue;
949 		};
950 		clearAttachments.push_back(clearAttachment);
951 	}
952 
953 	VkRect2D renderArea = makeRect2D(m_renderSize);
954 	std::vector<VkRenderingAttachmentInfoKHR> colorAttachments;
955 	for (size_t i = 0; i < m_colorAttachmentViews.size() ; ++i)
956 	{
957 		colorAttachments.push_back({
958 			VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,					// VkStructureType						sType;
959 			DE_NULL,															// const void*							pNext;
960 			(m_testParams.colorUsed[i]) ? *m_colorAttachmentViews[i] : 0,		// VkImageView							imageView;
961 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,							// VkImageLayout						imageLayout;
962 			VK_RESOLVE_MODE_NONE,												// VkResolveModeFlagBits				resolveMode;
963 			DE_NULL,															// VkImageView							resolveImageView;
964 			VK_IMAGE_LAYOUT_UNDEFINED,											// VkImageLayout						resolveImageLayout;
965 			VK_ATTACHMENT_LOAD_OP_LOAD,											// VkAttachmentLoadOp					loadOp;
966 			VK_ATTACHMENT_STORE_OP_STORE,										// VkAttachmentStoreOp					storeOp;
967 			m_clearColor														// VkClearValue							clearValue;
968 		});
969 	}
970 
971 	VkRenderingAttachmentInfoKHR depthAttachment
972 	{
973 		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,						// VkStructureType						sType;
974 		DE_NULL,																// const void*							pNext;
975 		(m_testParams.depthStencilUsed) ? *m_depthAttachmentView : 0,			// VkImageView							imageView;
976 		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,						// VkImageLayout						imageLayout;
977 		VK_RESOLVE_MODE_NONE,													// VkResolveModeFlagBits				resolveMode;
978 		DE_NULL,																// VkImageView							resolveImageView;
979 		VK_IMAGE_LAYOUT_UNDEFINED,												// VkImageLayout						resolveImageLayout;
980 		VK_ATTACHMENT_LOAD_OP_LOAD,												// VkAttachmentLoadOp					loadOp;
981 		VK_ATTACHMENT_STORE_OP_STORE,											// VkAttachmentStoreOp					storeOp;
982 		m_clearColorDepth														// VkClearValue							clearValue;
983 	};
984 
985 	const bool hasDepth		= (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
986 							  m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY) && m_testParams.depthStencilUsed;
987 	const bool hasStencil	= (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
988 							  m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY) && m_testParams.depthStencilUsed;
989 
990 	std::vector<VkFormat> colorAttachmentFormats(m_testParams.colorUsed.size(), VK_FORMAT_UNDEFINED);
991 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
992 		if (m_testParams.colorUsed[i])
993 			colorAttachmentFormats[i] = FORMAT_COLOR;
994 
995 	VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
996 	{
997 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,		// VkStructureType					sType;
998 		DE_NULL,																// const void*						pNext;
999 		0u,																		// VkRenderingFlagsKHR				flags;
1000 		0u,																		// uint32_t							viewMask;
1001 		static_cast<deUint32>(colorAttachmentFormats.size()),					// uint32_t							colorAttachmentCount;
1002 		colorAttachmentFormats.data(),											// const VkFormat*					pColorAttachmentFormats;
1003 		hasDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							depthAttachmentFormat;
1004 		hasStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							stencilAttachmentFormat;
1005 		VK_SAMPLE_COUNT_1_BIT,													// VkSampleCountFlagBits			rasterizationSamples;
1006 	};
1007 
1008 	const VkCommandBufferInheritanceInfo	bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
1009 	VkCommandBufferBeginInfo				commandBufBeginParams
1010 	{
1011 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
1012 		DE_NULL,																// const void*						pNext;
1013 		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,							// VkCommandBufferUsageFlags		flags;
1014 		&bufferInheritanceInfo
1015 	};
1016 
1017 	VkRenderingInfoKHR renderingInfo
1018 	{
1019 		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
1020 		DE_NULL,
1021 		0u,																		// VkRenderingFlagsKHR					flags;
1022 		renderArea,																// VkRect2D								renderArea;
1023 		1u,																		// deUint32								layerCount;
1024 		0u,																		// deUint32								viewMask;
1025 		static_cast<deUint32>(colorAttachments.size()),							// deUint32								colorAttachmentCount;
1026 		colorAttachments.empty() ? DE_NULL : colorAttachments.data(),			// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
1027 		hasDepth ? &depthAttachment : DE_NULL,									// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
1028 		hasStencil ? &depthAttachment : DE_NULL,								// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
1029 	};
1030 
1031 	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1032 
1033 	if (m_testParams.groupParams->useSecondaryCmdBuffer)
1034 	{
1035 		m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1036 
1037 		// record secondary command buffer
1038 		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1039 		{
1040 			inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1041 			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1042 			vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
1043 		}
1044 		else
1045 		{
1046 			commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1047 			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1048 		}
1049 
1050 		vk.cmdBindPipeline(*m_secCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1051 		if (!clearAttachments.empty())
1052 		{
1053 			vk.cmdClearAttachments(*m_secCmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
1054 		}
1055 
1056 		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1057 			vk.cmdEndRendering(*m_secCmdBuffer);
1058 		endCommandBuffer(vk, *m_secCmdBuffer);
1059 
1060 		// record primary command buffer
1061 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1062 		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1063 		{
1064 			renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1065 			vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1066 		}
1067 		vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
1068 		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1069 			vk.cmdEndRendering(*m_cmdBuffer);
1070 		endCommandBuffer(vk, *m_cmdBuffer);
1071 	}
1072 	else
1073 	{
1074 		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1075 		vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1076 
1077 		vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1078 		if (!clearAttachments.empty())
1079 		{
1080 			vk.cmdClearAttachments(*m_cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1u, &clearRect);
1081 		}
1082 
1083 		vk.cmdEndRendering(*m_cmdBuffer);
1084 		endCommandBuffer(vk, *m_cmdBuffer);
1085 	}
1086 }
1087 #endif // CTS_USES_VULKANSC
1088 
iterate(void)1089 tcu::TestStatus	UnusedClearAttachmentTestInstance::iterate (void)
1090 {
1091 	const DeviceInterface&	vk					= m_context.getDeviceInterface();
1092 	const VkDevice			vkDevice			= m_context.getDevice();
1093 	const VkQueue			queue				= m_context.getUniversalQueue();
1094 	const deUint32			queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1095 	SimpleAllocator			allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1096 
1097 	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1098 
1099 	// Read result images.
1100 	std::vector<de::MovePtr<tcu::TextureLevel>> imagePixels;
1101 	for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
1102 		imagePixels.emplace_back(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImages[i], FORMAT_COLOR, m_renderSize).release());
1103 
1104 	// Verify pixel colors match.
1105 	for (size_t i = 0; i < imagePixels.size(); ++i)
1106 	{
1107 		const tcu::ConstPixelBufferAccess&	imageAccess		= imagePixels[i]->getAccess();
1108 		const float*						refColor		= (m_testParams.colorUsed[i] ? m_clearColor.color.float32 : m_initialColor.color.float32);
1109 
1110 #ifdef CTS_USES_VULKANSC
1111 		if (m_context.getTestContext().getCommandLine().isSubProcess())
1112 #endif // CTS_USES_VULKANSC
1113 		{
1114 			for (int y = 0; y < imageAccess.getHeight(); ++y)
1115 			for (int x = 0; x < imageAccess.getWidth(); ++x)
1116 			{
1117 				const tcu::Vec4	color = imageAccess.getPixel(x, y);
1118 
1119 				for (deUint32 cpnt = 0; cpnt < 4; ++cpnt)
1120 					if (de::abs(color[cpnt] - refColor[cpnt]) > 0.01f)
1121 					{
1122 						std::ostringstream msg;
1123 
1124 						msg << "Attachment " << i << " with mismatched pixel (" << x << ", " << y << "): expecting pixel value [";
1125 						for (deUint32 j = 0; j < 4; ++j)
1126 							msg << ((j == 0) ? "" : ", ") << refColor[j];
1127 						msg << "] and found [";
1128 						for (deUint32 j = 0; j < 4; ++j)
1129 							msg << ((j == 0) ? "" : ", ") << color[j];
1130 						msg << "]";
1131 
1132 						return tcu::TestStatus::fail(msg.str());
1133 					}
1134 			}
1135 		}
1136 	}
1137 
1138 	if (hasDepthStencil(m_testParams.depthStencilType))
1139 	{
1140 		const bool depthOnly	= isDepthOnly(m_testParams.depthStencilType);
1141 		const bool stencilOnly	= isStencilOnly(m_testParams.depthStencilType);
1142 
1143 		if (!stencilOnly)
1144 		{
1145 			de::MovePtr<tcu::TextureLevel>		depthPixels	= pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize);
1146 			const tcu::ConstPixelBufferAccess&	depthAccess	= depthPixels->getAccess();
1147 			const float							refDepth	= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.depth : m_initialColorDepth.depthStencil.depth);
1148 
1149 #ifdef CTS_USES_VULKANSC
1150 			if (m_context.getTestContext().getCommandLine().isSubProcess())
1151 #endif // CTS_USES_VULKANSC
1152 			{
1153 				for (int y = 0; y < depthAccess.getHeight(); ++y)
1154 				for (int x = 0; x < depthAccess.getWidth(); ++x)
1155 				{
1156 					const float value = depthAccess.getPixDepth(x, y);
1157 					if (de::abs(value - refDepth) > 0.001f)
1158 					{
1159 						std::ostringstream msg;
1160 
1161 						msg << "Depth/stencil attachment with mismatched depth value at pixel ("
1162 							<< x << ", " << y << "): expected value " << refDepth << " and found " << value;
1163 						return tcu::TestStatus::fail(msg.str());
1164 					}
1165 				}
1166 			}
1167 		}
1168 
1169 		if (!depthOnly)
1170 		{
1171 			// Note read*Attachment leaves the attachment in the VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout, so the current layout
1172 			// depends on if we have previously read the depth aspect or not.
1173 			const VkImageLayout					currentLayout	= (stencilOnly ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1174 			de::MovePtr<tcu::TextureLevel>		stencilPixels	= pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage, m_testParams.depthStencilFormat, m_renderSize, currentLayout);
1175 			const tcu::ConstPixelBufferAccess&	stencilAccess	= stencilPixels->getAccess();
1176 			const deUint32						refStencil		= (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.stencil : m_initialColorDepth.depthStencil.stencil);
1177 
1178 #ifdef CTS_USES_VULKANSC
1179 			if (m_context.getTestContext().getCommandLine().isSubProcess())
1180 #endif // CTS_USES_VULKANSC
1181 			{
1182 				for (int y = 0; y < stencilAccess.getHeight(); ++y)
1183 				for (int x = 0; x < stencilAccess.getWidth(); ++x)
1184 				{
1185 					const int value = stencilAccess.getPixStencil(x, y);
1186 					if (value < 0 || static_cast<deUint32>(value) != refStencil)
1187 					{
1188 						std::ostringstream msg;
1189 
1190 						msg << "Depth/stencil attachment with mismatched stencil value at pixel ("
1191 							<< x << ", " << y << "): expected value " << refStencil << " and found " << value;
1192 						return tcu::TestStatus::fail(msg.str());
1193 					}
1194 				}
1195 			}
1196 		}
1197 	}
1198 
1199 	return tcu::TestStatus::pass("Pass");
1200 }
1201 
1202 
1203 using CallbackFunction = std::function<void(const std::vector<deBool>&)>;
1204 
runCallbackOnCombination(std::vector<deBool> & array,size_t current_index,CallbackFunction callback)1205 void runCallbackOnCombination(std::vector<deBool>& array, size_t current_index, CallbackFunction callback)
1206 {
1207 	DE_ASSERT(current_index < array.size());
1208 	for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
1209 	{
1210 		array[current_index] = DE_BOOL_VALUES[i];
1211 		if (current_index == array.size() - 1)
1212 			callback(array);
1213 		else
1214 			runCallbackOnCombination(array, current_index + 1, callback);
1215 	}
1216 }
1217 
runCallbackOnCombination(std::vector<deBool> & array,CallbackFunction callback)1218 void runCallbackOnCombination(std::vector<deBool>& array, CallbackFunction callback)
1219 {
1220 	runCallbackOnCombination(array, 0, callback);
1221 }
1222 
getUsed(deBool value)1223 std::string getUsed(deBool value)
1224 {
1225 	return (value ? "used" : "unused");
1226 }
1227 
getCombName(const std::vector<deBool> & array)1228 std::string getCombName(const std::vector<deBool>& array)
1229 {
1230 	std::ostringstream name;
1231 	for (size_t i = 0; i < array.size(); ++i)
1232 		name << ((i == 0)? "" : "_") << "color" << getUsed(array[i]);
1233 	return name.str();
1234 }
1235 
1236 } // anonymous
1237 
1238 
createRenderPassUnusedClearAttachmentTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1239 tcu::TestCaseGroup* createRenderPassUnusedClearAttachmentTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
1240 {
1241 	// Unused attachments with vkCmdClearAttachments
1242 	de::MovePtr<tcu::TestCaseGroup>	testGroup (new tcu::TestCaseGroup(testCtx, "unused_clear_attachments"));
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