• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * -----------------------------
4  *
5  * Copyright (c) 2020 Google Inc.
6  * Copyright (c) 2020 The Khronos Group Inc.
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 for multiple color or depth clears within a render pass
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktDrawMultipleClearsWithinRenderPass.hpp"
26 
27 #include "vktTestGroupUtil.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktDrawCreateInfoUtil.hpp"
30 #include "vktDrawBufferObjectUtil.hpp"
31 #include "vktDrawImageObjectUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "vktDrawTestCaseUtil.hpp"
41 
42 #include "deStringUtil.hpp"
43 
44 #include <cmath>
45 #include <vector>
46 #include <string>
47 #include <sstream>
48 
49 namespace vkt
50 {
51 namespace Draw
52 {
53 namespace
54 {
55 using namespace vk;
56 using tcu::Vec4;
57 using de::SharedPtr;
58 using std::string;
59 using std::abs;
60 using std::vector;
61 using std::ostringstream;
62 
63 const deUint32						WIDTH					= 400;
64 const deUint32						HEIGHT					= 300;
65 
66 enum struct Topology
67 {
68 	TRIANGLE_STRIP = 0,
69 	TRIANGLES,
70 	TRIANGLE
71 };
72 
73 const Topology						topologiesToTest[]		=
74 {
75 	Topology::TRIANGLE_STRIP,
76 	Topology::TRIANGLES,
77 	Topology::TRIANGLE
78 };
79 
80 struct FormatPair
81 {
82 	VkFormat colorFormat;
83 	VkFormat depthFormat;
84 };
85 
86 const FormatPair					formatsToTest[]			=
87 {
88 	{ VK_FORMAT_R8G8B8A8_UNORM	, VK_FORMAT_UNDEFINED	},
89 	{ VK_FORMAT_R8G8B8A8_SNORM	, VK_FORMAT_UNDEFINED	},
90 	{ VK_FORMAT_UNDEFINED		, VK_FORMAT_D32_SFLOAT	},
91 	{ VK_FORMAT_UNDEFINED		, VK_FORMAT_D16_UNORM	},
92 	{ VK_FORMAT_R8G8B8A8_UNORM	, VK_FORMAT_D32_SFLOAT	},
93 	{ VK_FORMAT_R8G8B8A8_UNORM	, VK_FORMAT_D16_UNORM	},
94 	{ VK_FORMAT_R8G8B8A8_SNORM	, VK_FORMAT_D32_SFLOAT	},
95 	{ VK_FORMAT_R8G8B8A8_SNORM	, VK_FORMAT_D16_UNORM	},
96 };
97 
98 const Vec4							verticesTriangleStrip[]	=
99 {
100 	Vec4(-1.0f, -1.0f,	0.0f, 1.0f),	// 0 -- 2
101 	Vec4(-1.0f,	 1.0f,	0.0f, 1.0f),	// |  / |
102 	Vec4( 1.0f, -1.0f,	0.0f, 1.0f),	// | /	|
103 	Vec4( 1.0f,	 1.0f,	0.0f, 1.0f)		// 1 -- 3
104 };
105 const Vec4							verticesTriangles[]		=
106 {
107 	Vec4(-1.0f, -1.0f,	0.0f, 1.0f),	// 0 - 1
108 	Vec4(-1.0f,	 1.0f,	0.0f, 1.0f),	// | /
109 	Vec4( 1.0f, -1.0f,	0.0f, 1.0f),	// 2
110 	Vec4( 1.0f, -1.0f,	0.0f, 1.0f),	//	   4
111 	Vec4(-1.0f,	 1.0f,	0.0f, 1.0f),	//	 / |
112 	Vec4( 1.0f,	 1.0f,	0.0f, 1.0f)		// 3 - 5
113 };
114 const Vec4							verticesBigTriangle[]	=
115 {
116 	Vec4(-1.0f, -1.0f,	0.0f, 1.0f),	// 0 - 2
117 	Vec4(-1.0f,	 3.0f,	0.0f, 1.0f),	// | /
118 	Vec4( 3.0f, -1.0f,	0.0f, 1.0f),	// 1
119 };
120 
121 const deUint32			TOPOLOGY_MAX_VERTICES_COUNT			= 6;
122 const deUint32			TEST_MAX_STEPS_COUNT				= 3;
123 
124 struct Vertices
125 {
126 	const char*			testNameSuffix;
127 	VkPrimitiveTopology	topology;
128 	deUint32			verticesCount;
129 	const Vec4*			vertices;
130 };
131 
132 const Vertices			verticesByTopology[]				=
133 {
134 	{
135 		"_triangle_strip",
136 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
137 		DE_LENGTH_OF_ARRAY(verticesTriangleStrip),
138 		verticesTriangleStrip
139 	},
140 	{
141 		"_triangles",
142 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
143 		DE_LENGTH_OF_ARRAY(verticesTriangles),
144 		verticesTriangles
145 	},
146 	{
147 		"_big_triangle",
148 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
149 		DE_LENGTH_OF_ARRAY(verticesBigTriangle),
150 		verticesBigTriangle
151 	}
152 };
153 
154 enum struct ClearOp
155 {
156 	LOAD = 0,
157 	DRAW,
158 	CLEAR
159 };
160 
161 struct ClearStep
162 {
163 	ClearOp					clearOp;
164 	Vec4					color;
165 	float					depth;
166 };
167 
168 struct TestParams
169 {
170 	VkFormat				colorFormat;
171 	VkFormat				depthFormat;
172 	Topology				topology;
173 	Vec4					expectedColor;
174 	float					colorEpsilon;
175 	float					expectedDepth;
176 	float					depthEpsilon;
177 	deUint32				repeatCount;
178 	bool					enableBlend;
179 	bool					useDynamicRendering;
180 	vector<ClearStep>		steps;
181 };
182 
183 class MultipleClearsTest : public TestInstance
184 {
185 public:
186 							MultipleClearsTest		(Context& context, const TestParams& params);
187 	virtual tcu::TestStatus	iterate					(void);
188 private:
189 	void					clearAttachments		(const DeviceInterface& vk, VkCommandBuffer cmdBuffer, const ClearOp clearOp, const size_t stepIndex);
190 
191 	SharedPtr<Image>		m_colorTargetImage;
192 	SharedPtr<Image>		m_depthTargetImage;
193 	Move<VkImageView>		m_colorTargetView;
194 	Move<VkImageView>		m_depthTargetView;
195 	SharedPtr<Buffer>		m_vertexBuffer;
196 	Move<VkRenderPass>		m_renderPass;
197 	Move<VkFramebuffer>		m_framebuffer;
198 	Move<VkPipelineLayout>	m_pipelineLayout;
199 	Move<VkPipeline>		m_pipeline;
200 
201 	const TestParams		m_params;
202 	Vec4					m_vertices[TOPOLOGY_MAX_VERTICES_COUNT * TEST_MAX_STEPS_COUNT];
203 };
204 
MultipleClearsTest(Context & context,const TestParams & params)205 MultipleClearsTest::MultipleClearsTest (Context &context, const TestParams& params)
206 	: TestInstance(context)
207 	, m_params(params)
208 {
209 	const DeviceInterface&		vk					= m_context.getDeviceInterface();
210 	const VkDevice				device				= m_context.getDevice();
211 	const deUint32				queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
212 	const bool					hasColor			= m_params.colorFormat != VK_FORMAT_UNDEFINED;
213 	const bool					hasDepth			= m_params.depthFormat != VK_FORMAT_UNDEFINED;
214 
215 	DescriptorSetLayoutBuilder	descriptorSetLayoutBuilder;
216 	// Vertex data
217 	const auto&					vertexData			= verticesByTopology[(size_t)m_params.topology];
218 	{
219 		DE_ASSERT(vertexData.verticesCount <= TOPOLOGY_MAX_VERTICES_COUNT);
220 		const size_t			verticesCount		= vertexData.verticesCount;
221 		const VkDeviceSize		dataSize			= verticesCount * sizeof(Vec4);
222 		const VkDeviceSize		totalDataSize		= m_params.steps.size() * dataSize;
223 		DE_ASSERT(totalDataSize <= sizeof(m_vertices));
224 
225 		for(size_t i = 0; i < m_params.steps.size(); ++i)
226 		{
227 			const size_t start = i * verticesCount;
228 			deMemcpy(&m_vertices[start], vertexData.vertices, static_cast<size_t>(dataSize));
229 			for(size_t j = 0; j < verticesCount; ++j)
230 				m_vertices[start + j][2] = m_params.steps[i].depth;
231 		}
232 		m_vertexBuffer								= Buffer::createAndAlloc(vk, device, BufferCreateInfo(totalDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
233 																			 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
234 		deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices, static_cast<std::size_t>(totalDataSize));
235 		flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
236 	}
237 
238 	if (hasColor)
239 	{
240 		const VkImageUsageFlags		targetImageUsageFlags		= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
241 		const ImageCreateInfo		targetImageCreateInfo		(VK_IMAGE_TYPE_2D, m_params.colorFormat, { WIDTH, HEIGHT, 1u }, 1u,	1u,	VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, targetImageUsageFlags);
242 		m_colorTargetImage										= Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
243 		const ImageViewCreateInfo	colorTargetViewInfo			(m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_params.colorFormat);
244 		m_colorTargetView										= createImageView(vk, device, &colorTargetViewInfo);
245 	}
246 
247 	if (hasDepth)
248 	{
249 		const VkImageUsageFlags		depthImageUsageFlags		= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
250 		const ImageCreateInfo		depthImageCreateInfo		(VK_IMAGE_TYPE_2D, m_params.depthFormat, { WIDTH, HEIGHT, 1u }, 1u,	1u,	VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, depthImageUsageFlags);
251 		m_depthTargetImage										= Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
252 		const ImageViewCreateInfo	depthTargetViewInfo			(m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_params.depthFormat);
253 		m_depthTargetView										= createImageView(vk, device, &depthTargetViewInfo);
254 	}
255 
256 	// Render pass
257 	if (!m_params.useDynamicRendering)
258 	{
259 		RenderPassCreateInfo			renderPassCreateInfo;
260 		if (hasColor)
261 		{
262 			renderPassCreateInfo.addAttachment(AttachmentDescription(
263 				 m_params.colorFormat,								// format
264 				 VK_SAMPLE_COUNT_1_BIT,								// samples
265 				 VK_ATTACHMENT_LOAD_OP_LOAD,						// loadOp
266 				 VK_ATTACHMENT_STORE_OP_STORE,						// storeOp
267 				 VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// stencilLoadOp
268 				 VK_ATTACHMENT_STORE_OP_DONT_CARE,					// stencilStoreOp
269 				 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// initialLayout
270 				 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));		// finalLayout
271 		}
272 		if (hasDepth)
273 		{
274 			renderPassCreateInfo.addAttachment(AttachmentDescription(
275 				m_params.depthFormat,								// format
276 				VK_SAMPLE_COUNT_1_BIT,								// samples
277 				VK_ATTACHMENT_LOAD_OP_LOAD,							// loadOp
278 				VK_ATTACHMENT_STORE_OP_STORE,						// storeOp
279 				VK_ATTACHMENT_LOAD_OP_DONT_CARE,					// stencilLoadOp
280 				VK_ATTACHMENT_STORE_OP_DONT_CARE,					// stencilStoreOp
281 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// initialLayout
282 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL));	// finalLayout
283 		}
284 		const VkAttachmentReference colorAttachmentReference		= hasColor ? makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) : AttachmentReference();
285 		const VkAttachmentReference depthAttachmentReference		= hasDepth ? makeAttachmentReference(hasColor ? 1u : 0u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) : AttachmentReference();
286 		renderPassCreateInfo.addSubpass(SubpassDescription(
287 			VK_PIPELINE_BIND_POINT_GRAPHICS,						// pipelineBindPoint
288 			(VkSubpassDescriptionFlags)0,							// flags
289 			0u,														// inputAttachmentCount
290 			DE_NULL,												// inputAttachments
291 			hasColor ? 1 : 0,										// colorAttachmentCount
292 			hasColor ? &colorAttachmentReference : DE_NULL,			// colorAttachments
293 			DE_NULL,												// resolveAttachments
294 			depthAttachmentReference,								// depthStencilAttachment
295 			0u,														// preserveAttachmentCount
296 			DE_NULL));												// preserveAttachments
297 		m_renderPass												= createRenderPass(vk, device, &renderPassCreateInfo);
298 
299 		std::vector<VkImageView> attachments;
300 		if (hasColor)
301 			attachments.push_back(*m_colorTargetView);
302 		if (hasDepth)
303 			attachments.push_back(*m_depthTargetView);
304 		const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
305 		m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
306 	}
307 
308 	// Vertex input
309 	const VkVertexInputBindingDescription		vertexInputBindingDescription	=
310 	{
311 		0u,										// uint32_t				binding;
312 		sizeof(Vec4),							// uint32_t				stride;
313 		VK_VERTEX_INPUT_RATE_VERTEX,			// VkVertexInputRate	inputRate;
314 	};
315 
316 	const VkVertexInputAttributeDescription		vertexInputAttributeDescription =
317 	{
318 		0u,										// uint32_t		location;
319 		0u,										// uint32_t		binding;
320 		VK_FORMAT_R32G32B32A32_SFLOAT,			// VkFormat		format;
321 		0u										// uint32_t		offset;
322 	};
323 
324 	const PipelineCreateInfo::VertexInputState	vertexInputState				= PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
325 																													   1, &vertexInputAttributeDescription);
326 
327 	// Graphics pipeline
328 	const Unique<VkShaderModule>				vertexModule					(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
329 	const Unique<VkShaderModule>				fragmentModule					(createShaderModule(vk, device, m_context.getBinaryCollection().get(hasColor ? "frag" : "frag_depthonly"), 0));
330 
331 	const VkPushConstantRange					pcRange							= vk::VkPushConstantRange { VkShaderStageFlagBits::VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ClearStep::color) };
332 	const PipelineLayoutCreateInfo				pipelineLayoutCreateInfo		(0u, DE_NULL, 1u, &pcRange);
333 	m_pipelineLayout															= createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
334 
335 	const VkRect2D								scissor							= makeRect2D(WIDTH, HEIGHT);
336 	const VkViewport							viewport						= makeViewport(WIDTH, HEIGHT);
337 
338 	const auto									vkCbAttachmentState				= makePipelineColorBlendAttachmentState(
339 		m_params.enableBlend ? VK_TRUE : VK_FALSE,	// VkBool32					blendEnable
340 		VK_BLEND_FACTOR_SRC_ALPHA,					// VkBlendFactor			srcColorBlendFactor
341 		VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,		// VkBlendFactor			dstColorBlendFactor
342 		VK_BLEND_OP_ADD,							// VkBlendOp				colorBlendOp
343 		VK_BLEND_FACTOR_ZERO,						// VkBlendFactor			srcAlphaBlendFactor
344 		VK_BLEND_FACTOR_ONE,						// VkBlendFactor			dstAlphaBlendFactor
345 		VK_BLEND_OP_ADD,							// VkBlendOp				alphaBlendOp
346 		VK_COLOR_COMPONENT_R_BIT |					// VkColorComponentFlags	colorWriteMask
347 		VK_COLOR_COMPONENT_G_BIT |
348 		VK_COLOR_COMPONENT_B_BIT |
349 		VK_COLOR_COMPONENT_A_BIT);
350 	PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
351 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule,	  "main", VK_SHADER_STAGE_VERTEX_BIT));
352 	pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
353 	pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState	(vertexInputState));
354 	pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(vertexData.topology));
355 	pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState	(1, &vkCbAttachmentState));
356 	pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState		(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
357 	pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState	(hasDepth, hasDepth, VK_COMPARE_OP_ALWAYS, VK_FALSE, VK_FALSE));
358 	pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState	());
359 	pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState	());
360 
361 	vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo
362 	{
363 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
364 		DE_NULL,
365 		0u,
366 		hasColor,
367 		(hasColor ? &m_params.colorFormat : DE_NULL),
368 		(hasDepth ? m_params.depthFormat : VK_FORMAT_UNDEFINED),
369 		(hasDepth ? m_params.depthFormat : VK_FORMAT_UNDEFINED)
370 	};
371 
372 	if (m_params.useDynamicRendering)
373 		pipelineCreateInfo.pNext = &renderingCreateInfo;
374 
375 	m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
376 }
377 
clearAttachments(const DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,const ClearOp clearOp,const size_t stepIndex)378 void MultipleClearsTest::clearAttachments (const DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, const ClearOp clearOp, const size_t stepIndex)
379 {
380 	const Vec4& color = m_params.steps[stepIndex].color;
381 	const float depth = m_params.steps[stepIndex].depth;
382 	switch(clearOp) {
383 	case ClearOp::LOAD:
384 		break;
385 	case ClearOp::DRAW:
386 		{
387 			const auto&		vertexData		= verticesByTopology[(size_t)m_params.topology];
388 			const deUint32	verticesCount	= vertexData.verticesCount;
389 			vk.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(color), color.getPtr());
390 			vk.cmdDraw(cmdBuffer, verticesCount, 1, static_cast<deUint32>(verticesCount * stepIndex), 0);
391 		}
392 		break;
393 	case ClearOp::CLEAR:
394 		{
395 			vector<VkClearAttachment>	clearAttachments;
396 			if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
397 			{
398 				const VkClearAttachment	clearAttachment	=
399 				{
400 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags	 aspectMask
401 					static_cast<deUint32>(clearAttachments.size()),	// uint32_t				 colorAttachment
402 					makeClearValueColor(color)						// VkClearValue			 clearValue
403 				};
404 				clearAttachments.push_back(clearAttachment);
405 			}
406 			if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
407 			{
408 				const VkClearAttachment	clearAttachment	=
409 				{
410 					VK_IMAGE_ASPECT_DEPTH_BIT,						// VkImageAspectFlags	 aspectMask
411 					static_cast<deUint32>(clearAttachments.size()),	// uint32_t				 colorAttachment
412 					makeClearValueDepthStencil(depth, 0)			// VkClearValue			 clearValue
413 				};
414 				clearAttachments.push_back(clearAttachment);
415 			}
416 			const VkClearRect			clearRect		=
417 			{
418 				makeRect2D(WIDTH, HEIGHT),							// VkRect2D	   rect
419 				0,													// uint32_t	   baseArrayLayer
420 				1													// uint32_t	   layerCount
421 			};
422 			vk.cmdClearAttachments(cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1, &clearRect);
423 		}
424 		break;
425 	default:
426 		break;
427 	}
428 }
429 
iterate(void)430 tcu::TestStatus MultipleClearsTest::iterate (void)
431 {
432 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
433 	const VkDevice					device				= m_context.getDevice();
434 	const VkQueue					queue				= m_context.getUniversalQueue();
435 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
436 
437 	const CmdPoolCreateInfo			cmdPoolCreateInfo	(queueFamilyIndex);
438 	const Unique<VkCommandPool>		cmdPool				(createCommandPool(vk, device, &cmdPoolCreateInfo));
439 	const Unique<VkCommandBuffer>	cmdBuffer			(allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
440 
441 	const bool						hasColor			= m_params.colorFormat != VK_FORMAT_UNDEFINED;
442 	const bool						hasDepth			= m_params.depthFormat != VK_FORMAT_UNDEFINED;
443 
444 	beginCommandBuffer(vk, *cmdBuffer);
445 	if (hasColor)
446 		initialTransitionColor2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
447 	if (hasDepth)
448 		initialTransitionDepth2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
449 
450 	const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
451 	if (m_params.useDynamicRendering)
452 	{
453 		VkClearValue clearColorValue = makeClearValueColor(tcu::Vec4(0.0f));
454 		VkClearValue clearDepthValue = makeClearValueDepthStencil(0.0f, 0u);
455 		if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
456 		{
457 			clearColorValue = makeClearValueColor(m_params.steps[0].color);
458 			clearDepthValue = makeClearValueDepthStencil(m_params.steps[0].depth, 0u);
459 		}
460 
461 		vk::VkRenderingAttachmentInfoKHR colorAttachment
462 		{
463 			vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
464 			DE_NULL,												// const void*							pNext;
465 			*m_colorTargetView,										// VkImageView							imageView;
466 			vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,			// VkImageLayout						imageLayout;
467 			vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
468 			DE_NULL,												// VkImageView							resolveImageView;
469 			vk::VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout						resolveImageLayout;
470 			vk::VK_ATTACHMENT_LOAD_OP_LOAD,							// VkAttachmentLoadOp					loadOp;
471 			vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
472 			clearColorValue											// VkClearValue							clearValue;
473 		};
474 
475 		vk::VkRenderingAttachmentInfoKHR depthAttachment
476 		{
477 			vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
478 			DE_NULL,												// const void*							pNext;
479 			*m_depthTargetView,										// VkImageView							imageView;
480 			vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,	// VkImageLayout						imageLayout;
481 			vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
482 			DE_NULL,												// VkImageView							resolveImageView;
483 			vk::VK_IMAGE_LAYOUT_UNDEFINED,							// VkImageLayout						resolveImageLayout;
484 			vk::VK_ATTACHMENT_LOAD_OP_LOAD,							// VkAttachmentLoadOp					loadOp;
485 			vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
486 			clearDepthValue											// VkClearValue							clearValue;
487 		};
488 
489 		vk::VkRenderingInfoKHR renderingInfo
490 		{
491 			vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
492 			DE_NULL,
493 			0u,														// VkRenderingFlagsKHR					flags;
494 			renderArea,												// VkRect2D								renderArea;
495 			1u,														// deUint32								layerCount;
496 			0u,														// deUint32								viewMask;
497 			hasColor,												// deUint32								colorAttachmentCount;
498 			(hasColor ? &colorAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
499 			(hasDepth ? &depthAttachment : DE_NULL),				// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
500 			DE_NULL,												// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
501 		};
502 
503 		vk.cmdBeginRenderingKHR(*cmdBuffer, &renderingInfo);
504 	}
505 	else
506 	{
507 		if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
508 			beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, m_params.steps[0].color, m_params.steps[0].depth, 0);
509 		else
510 			beginRenderPass(vk, *cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
511 	}
512 
513 	vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
514 	{
515 		const VkDeviceSize	offset	= 0;
516 		const VkBuffer		buffer	= m_vertexBuffer->object();
517 		vk.cmdBindVertexBuffers(*cmdBuffer, 0, 1, &buffer, &offset);
518 	}
519 	for(deUint32 i = 0; i < m_params.repeatCount; ++i)
520 		for(size_t j = 0; j < m_params.steps.size(); ++j)
521 		{
522 			const auto& step = m_params.steps[j];
523 			// ClearOp::LOAD only supported for first step
524 			DE_ASSERT(j == 0 || step.clearOp != ClearOp::LOAD);
525 			clearAttachments(vk, *cmdBuffer, step.clearOp, j);
526 		}
527 
528 	if (m_params.useDynamicRendering)
529 		endRendering(vk, *cmdBuffer);
530 	else
531 		endRenderPass(vk, *cmdBuffer);
532 
533 	if (hasDepth)
534 	{
535 		const VkMemoryBarrier	memBarrier	= { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT };
536 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
537 	}
538 	if (hasColor)
539 	{
540 		const VkMemoryBarrier	memBarrier	= { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT };
541 		vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
542 	}
543 
544 	if (hasColor)
545 		transition2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
546 						  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
547 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
548 						  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT);
549 	if (hasDepth)
550 		transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_ASPECT_DEPTH_BIT,
551 						  VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
552 						  VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
553 						  VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_HOST_BIT);
554 
555 	endCommandBuffer(vk, *cmdBuffer);
556 	submitCommandsAndWait(vk, device, queue, *cmdBuffer);
557 
558 	VK_CHECK(vk.queueWaitIdle(queue));
559 
560 	if (hasColor)
561 	{
562 		const auto		resultImage	= m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
563 
564 		for(int z = 0; z < resultImage.getDepth(); ++z)
565 		for(int y = 0; y < resultImage.getHeight(); ++y)
566 		for(int x = 0; x < resultImage.getWidth(); ++x)
567 		{
568 			const Vec4	difference	= m_params.expectedColor - resultImage.getPixel(x,y,z);
569 			if (abs(difference.x()) >= m_params.colorEpsilon || abs(difference.y()) >= m_params.colorEpsilon || abs(difference.z()) >= m_params.colorEpsilon)
570 			{
571 				ostringstream msg;
572 				msg << "Color value mismatch, expected: " << m_params.expectedColor << ", got: " << resultImage.getPixel(x,y,z) << " at " << "(" << x << ", " << y << ", " << z << ")";
573 				return tcu::TestStatus::fail(msg.str());
574 			}
575 		}
576 	}
577 	if (hasDepth)
578 	{
579 		const auto		resultImage	= m_depthTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_DEPTH_BIT);
580 
581 		for(int z = 0; z < resultImage.getDepth(); ++z)
582 		for(int y = 0; y < resultImage.getHeight(); ++y)
583 		for(int x = 0; x < resultImage.getWidth(); ++x)
584 		{
585 			const float	difference	= m_params.expectedDepth - resultImage.getPixDepth(x,y,z);
586 			if (abs(difference) >= m_params.depthEpsilon)
587 			{
588 				ostringstream msg;
589 				msg << "Depth value mismatch, expected: " << m_params.expectedDepth << ", got: " << resultImage.getPixDepth(x,y,z) << " at " << "(" << x << ", " << y << ", " << z << ")";
590 				return tcu::TestStatus::fail(msg.str());
591 			}
592 		}
593 	}
594 	return tcu::TestStatus::pass("Pass");
595 }
596 
597 class MultipleClearsWithinRenderPassTest : public TestCase
598 {
599 public:
MultipleClearsWithinRenderPassTest(tcu::TestContext & testCtx,const string & name,const string & description,const TestParams & params)600 	MultipleClearsWithinRenderPassTest (tcu::TestContext& testCtx, const string& name, const string& description, const TestParams& params)
601 		: TestCase(testCtx, name, description)
602 		, m_params(params)
603 	{
604 		DE_ASSERT(m_params.steps.size() <= static_cast<size_t>(TEST_MAX_STEPS_COUNT));
605 	}
606 
initPrograms(SourceCollections & programCollection) const607 	virtual void initPrograms (SourceCollections& programCollection) const
608 	{
609 		{
610 			ostringstream src;
611 			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
612 				<< "\n"
613 				<< "layout(location = 0) in vec4 in_position;\n"
614 				<< "\n"
615 				<< "out gl_PerVertex {\n"
616 				<< "    vec4  gl_Position;\n"
617 				<< "};\n"
618 				<< "\n"
619 				<< "void main(void)\n"
620 				<< "{\n"
621 				<< "    gl_Position = in_position;\n"
622 				<< "}\n";
623 			programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
624 		}
625 		{
626 			ostringstream src;
627 			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
628 				<< "\n"
629 				<< "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
630 				<< "layout(location = 0) out vec4 out_color;\n"
631 				<< "\n"
632 				<< "void main(void)\n"
633 				<< "{\n"
634 				<< "    out_color = u_color.color;\n"
635 				<< "}\n";
636 			programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
637 		}
638 		{
639 			ostringstream src;
640 			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
641 				<< "\n"
642 				<< "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
643 				<< "\n"
644 				<< "void main(void)\n"
645 				<< "{\n"
646 				<< "}\n";
647 			programCollection.glslSources.add("frag_depthonly") << glu::FragmentSource(src.str());
648 		}
649 	}
650 
checkSupport(Context & context) const651 	virtual void checkSupport (Context& context) const
652 	{
653 		VkImageFormatProperties imageFormatProperties;
654 		const auto&	vki	= context.getInstanceInterface();
655 		const auto&	vkd	= context.getPhysicalDevice();
656 		if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
657 		{
658 			const auto	colorUsage	= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
659 			if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.colorFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, colorUsage, 0u, &imageFormatProperties) != VK_SUCCESS)
660 				TCU_THROW(NotSupportedError, "Color format not supported");
661 		}
662 		if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
663 		{
664 			const auto	depthUsage	= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
665 			if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.depthFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, depthUsage, 0u, &imageFormatProperties) != VK_SUCCESS)
666 				TCU_THROW(NotSupportedError, "Depth format not supported");
667 		}
668 
669 		if (m_params.useDynamicRendering)
670 			context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
671 	}
672 
createInstance(Context & context) const673 	virtual TestInstance* createInstance (Context& context) const
674 	{
675 		return new MultipleClearsTest(context, m_params);
676 	}
677 
678 private:
679 	const TestParams	m_params;
680 };
681 
682 }	// anonymous
683 
MultipleClearsWithinRenderPassTests(tcu::TestContext & testCtx,bool useDynamicRendering)684 MultipleClearsWithinRenderPassTests::MultipleClearsWithinRenderPassTests (tcu::TestContext &testCtx, bool useDynamicRendering)
685 	: TestCaseGroup	(testCtx, "multiple_clears_within_render_pass", "Tests for multiple clears within render pass")
686 	, m_useDynamicRendering(useDynamicRendering)
687 {
688 }
689 
~MultipleClearsWithinRenderPassTests()690 MultipleClearsWithinRenderPassTests::~MultipleClearsWithinRenderPassTests ()
691 {
692 }
693 
init()694 void MultipleClearsWithinRenderPassTests::init ()
695 {
696 	for(const auto &formatPair : formatsToTest)
697 	{
698 		ostringstream			formatSuffix;
699 		if (formatPair.colorFormat != VK_FORMAT_UNDEFINED)
700 			formatSuffix << "_c" << de::toLower(string(getFormatName(formatPair.colorFormat)).substr(9));
701 		if (formatPair.depthFormat != VK_FORMAT_UNDEFINED)
702 			formatSuffix << "_d" << de::toLower(string(getFormatName(formatPair.depthFormat)).substr(9));
703 		for(const auto &topology : topologiesToTest)
704 		{
705 			const string	testNameSuffix	= formatSuffix.str() + verticesByTopology[(deUint32)topology].testNameSuffix;
706 			{
707 				const TestParams params	=
708 				{
709 					formatPair.colorFormat,			// VkFormat				colorFormat;
710 					formatPair.depthFormat,			// VkFormat				depthFormat;
711 					topology,						// Topology				topology;
712 					Vec4(0.0f, 0.5f, 0.5f, 1.0f),	// Vec4					expectedColor;
713 					0.01f,							// float				colorEpsilon;
714 					0.9f,							// float				expectedDepth;
715 					0.01f,							// float				depthEpsilon;
716 					1u,								// deUint32				repeatCount;
717 					true,							// bool					enableBlend;
718 					m_useDynamicRendering,			// bool					useDynamicRendering;
719 					{								// vector<ClearStep>	steps;
720 						{ ClearOp::LOAD		, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.7f },
721 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.3f },
722 						{ ClearOp::DRAW		, Vec4(0.0f, 0.0f, 1.0f, 0.5f)	, 0.9f }
723 					}
724 				};
725 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: load, clear, draw", params));
726 			}
727 			{
728 				const TestParams params	=
729 				{
730 					formatPair.colorFormat,			// VkFormat				format;
731 					formatPair.depthFormat,			// VkFormat				depthFormat;
732 					topology,						// Topology				topology;
733 					Vec4(0.0f, 0.5f, 0.5f, 1.0f),	// Vec4					expectedColor;
734 					0.01f,							// float				colorEpsilon;
735 					0.9f,							// float				expectedDepth;
736 					0.01f,							// float				depthEpsilon;
737 					1u,								// deUint32				repeatCount;
738 					true,							// bool					enableBlend;
739 					m_useDynamicRendering,			// bool					useDynamicRendering;
740 					{								// vector<ClearStep>	steps;
741 						{ ClearOp::DRAW		, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.7f },
742 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.3f },
743 						{ ClearOp::DRAW		, Vec4(0.0f, 0.0f, 1.0f, 0.5f)	, 0.9f }
744 					}
745 				};
746 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: draw, clear, draw", params));
747 			}
748 			{
749 				const TestParams params	=
750 				{
751 					formatPair.colorFormat,			// VkFormat				format;
752 					formatPair.depthFormat,			// VkFormat				depthFormat;
753 					topology,						// Topology				topology;
754 					Vec4(0.0f, 0.5f, 0.5f, 1.0f),	// Vec4					expectedColor;
755 					0.01f,							// float				colorEpsilon;
756 					0.9f,							// float				expectedDepth;
757 					0.01f,							// float				depthEpsilon;
758 					1u,								// deUint32				repeatCount;
759 					true,							// bool					enableBlend;
760 					m_useDynamicRendering,			// bool					useDynamicRendering;
761 					{								// vector<ClearStep>	steps;
762 						{ ClearOp::CLEAR	, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.7f },
763 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.3f },
764 						{ ClearOp::DRAW		, Vec4(0.0f, 0.0f, 1.0f, 0.5f)	, 0.9f }
765 					}
766 				};
767 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: clear, clear, draw", params));
768 			}
769 			{
770 				const TestParams params	=
771 				{
772 					formatPair.colorFormat,			// VkFormat				format;
773 					formatPair.depthFormat,			// VkFormat				depthFormat;
774 					topology,						// Topology				topology;
775 					Vec4(0.0f, 1.0f, 0.0f, 1.0f),	// Vec4					expectedColor;
776 					0.01f,							// float				colorEpsilon;
777 					0.9f,							// float				expectedDepth;
778 					0.01f,							// float				depthEpsilon;
779 					1u,								// deUint32				repeatCount;
780 					false,							// bool					enableBlend;
781 					m_useDynamicRendering,			// bool					useDynamicRendering;
782 					{								// vector<ClearStep>	steps;
783 						{ ClearOp::LOAD		, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.3f },
784 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.9f }
785 					}
786 				};
787 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear" + testNameSuffix, "Multiple clears within same render pass, methods: load, clear", params));
788 			}
789 			{
790 				const TestParams params	=
791 				{
792 					formatPair.colorFormat,			// VkFormat				format;
793 					formatPair.depthFormat,			// VkFormat				depthFormat;
794 					topology,						// Topology				topology;
795 					Vec4(0.0f, 1.0f, 0.0f, 1.0f),	// Vec4					expectedColor;
796 					0.01f,							// float				colorEpsilon;
797 					0.9f,							// float				expectedDepth;
798 					0.01f,							// float				depthEpsilon;
799 					1u,								// deUint32				repeatCount;
800 					false,							// bool					enableBlend;
801 					m_useDynamicRendering,			// bool					useDynamicRendering;
802 					{								// vector<ClearStep>	steps;
803 						{ ClearOp::DRAW		, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.3f },
804 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.9f }
805 					}
806 				};
807 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear" + testNameSuffix, "Multiple clears within same render pass, methods: draw, clear", params));
808 			}
809 			{
810 				const TestParams params	=
811 				{
812 					formatPair.colorFormat,			// VkFormat				format;
813 					formatPair.depthFormat,			// VkFormat				depthFormat;
814 					topology,						// Topology				topology;
815 					Vec4(0.0f, 1.0f, 0.0f, 1.0f),	// Vec4					expectedColor;
816 					0.01f,							// float				colorEpsilon;
817 					0.9f,							// float				expectedDepth;
818 					0.01f,							// float				depthEpsilon;
819 					1u,								// deUint32				repeatCount;
820 					false,							// bool					enableBlend;
821 					m_useDynamicRendering,			// bool					useDynamicRendering;
822 					{								// vector<ClearStep>	steps;
823 						{ ClearOp::CLEAR	, Vec4(1.0f, 0.0f, 0.0f, 1.0f)	, 0.3f },
824 						{ ClearOp::CLEAR	, Vec4(0.0f, 1.0f, 0.0f, 1.0f)	, 0.9f }
825 					}
826 				};
827 				addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear" + testNameSuffix, "Multiple clears within same render pass, methods: clear, clear", params));
828 			}
829 		}
830 	}
831 }
832 }	// Draw
833 }	// vkt
834