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