1/*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 The Khronos Group Inc.
6 * Copyright (c) 2021 Google 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 load and store op "none"
23 *//*--------------------------------------------------------------------*/
24
25#include "vktRenderPassLoadStoreOpNoneTests.hpp"
26#include "pipeline/vktPipelineImageUtil.hpp"
27#include "vktRenderPassTestsUtil.hpp"
28#include "vktTestCase.hpp"
29#include "vkImageUtil.hpp"
30#include "vkMemUtil.hpp"
31#include "vkPrograms.hpp"
32#include "vkQueryUtil.hpp"
33#include "vkCmdUtil.hpp"
34#include "vkRef.hpp"
35#include "vkRefUtil.hpp"
36#include "vkTypeUtil.hpp"
37#include "vkObjUtil.hpp"
38#include "tcuImageCompare.hpp"
39#include "tcuPlatform.hpp"
40#include "tcuTestLog.hpp"
41#include "tcuTextureUtil.hpp"
42#include "deStringUtil.hpp"
43#include "deUniquePtr.hpp"
44#include "deRandom.hpp"
45#include <cstring>
46#include <cmath>
47#include <vector>
48
49namespace vkt
50{
51namespace renderpass
52{
53
54using namespace vk;
55
56namespace
57{
58
59enum AttachmentInit
60{
61	ATTACHMENT_INIT_PRE = 1,
62	ATTACHMENT_INIT_CMD_CLEAR = 2
63};
64
65enum AttachmentUsage
66{
67	ATTACHMENT_USAGE_UNDEFINED = 0,
68	ATTACHMENT_USAGE_COLOR = 1,
69	ATTACHMENT_USAGE_DEPTH = 2,
70	ATTACHMENT_USAGE_STENCIL = 4,
71	ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL,
72	ATTACHMENT_USAGE_INPUT = 8,
73	ATTACHMENT_USAGE_COLOR_WRITE_OFF = 16,
74	ATTACHMENT_USAGE_DEPTH_WRITE_OFF = 32,
75	ATTACHMENT_USAGE_STENCIL_WRITE_OFF = 64,
76	ATTACHMENT_USAGE_DEPTH_TEST_OFF = 128,
77	ATTACHMENT_USAGE_STENCIL_TEST_OFF = 256,
78	ATTACHMENT_USAGE_MULTISAMPLE = 512,
79	ATTACHMENT_USAGE_RESOLVE_TARGET = 1024,
80	ATTACHMENT_USAGE_INTEGER = 2048
81};
82
83struct VerifyAspect
84{
85	VkImageAspectFlagBits	aspect;
86	bool					verifyInner;
87	tcu::Vec4				innerRef;
88	bool					verifyOuter;
89	tcu::Vec4				outerRef;
90};
91
92struct AttachmentParams
93{
94	deUint32					usage;
95	VkAttachmentLoadOp			loadOp;
96	VkAttachmentStoreOp			storeOp;
97	VkAttachmentLoadOp			stencilLoadOp;
98	VkAttachmentStoreOp			stencilStoreOp;
99	deUint32					init;
100	std::vector<VerifyAspect>	verifyAspects;
101};
102
103struct AttachmentRef
104{
105	deUint32	idx;
106	deUint32	usage;
107};
108
109struct SubpassParams
110{
111	std::vector<AttachmentRef>	attachmentRefs;
112	deUint32					numDraws;
113};
114
115struct TestParams
116{
117	std::vector<AttachmentParams>	attachments;
118	std::vector<SubpassParams>		subpasses;
119	const SharedGroupParams			groupParams;
120	VkFormat						depthStencilFormat;
121	bool							alphaBlend;
122};
123
124struct Vertex4RGBA
125{
126	tcu::Vec4 position;
127	tcu::Vec4 color;
128};
129
130template<typename T>
131inline de::SharedPtr<vk::Move<T> > makeSharedPtr(vk::Move<T> move)
132{
133	return de::SharedPtr<vk::Move<T> >(new vk::Move<T>(move));
134}
135
136std::vector<Vertex4RGBA> createQuad (void)
137{
138	std::vector<Vertex4RGBA>	vertices;
139
140	const float			size					= 1.0f;
141	const tcu::Vec4		red						(1.0f, 0.0f, 0.0f, 1.0f);
142	const tcu::Vec4		blue					(0.0f, 0.0f, 1.0f, 1.0f);
143	const Vertex4RGBA	lowerLeftVertexRed		= {tcu::Vec4(-size, -size, 0.0f, 1.0f), red};
144	const Vertex4RGBA	lowerRightVertexRed		= {tcu::Vec4(size, -size, 0.0f, 1.0f), red};
145	const Vertex4RGBA	upperLeftVertexRed		= {tcu::Vec4(-size, size, 0.0f, 1.0f), red};
146	const Vertex4RGBA	upperRightVertexRed		= {tcu::Vec4(size, size, 0.0f, 1.0f), red};
147	const Vertex4RGBA	lowerLeftVertexBlue		= {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue};
148	const Vertex4RGBA	lowerRightVertexBlue	= {tcu::Vec4(size, -size, 0.0f, 1.0f), blue};
149	const Vertex4RGBA	upperLeftVertexBlue		= {tcu::Vec4(-size, size, 0.0f, 1.0f), blue};
150	const Vertex4RGBA	upperRightVertexBlue	= {tcu::Vec4(size, size, 0.0f, 1.0f), blue};
151
152	vertices.push_back(lowerLeftVertexRed);
153	vertices.push_back(lowerRightVertexRed);
154	vertices.push_back(upperLeftVertexRed);
155	vertices.push_back(upperLeftVertexRed);
156	vertices.push_back(lowerRightVertexRed);
157	vertices.push_back(upperRightVertexRed);
158
159	vertices.push_back(lowerLeftVertexBlue);
160	vertices.push_back(lowerRightVertexBlue);
161	vertices.push_back(upperLeftVertexBlue);
162	vertices.push_back(upperLeftVertexBlue);
163	vertices.push_back(lowerRightVertexBlue);
164	vertices.push_back(upperRightVertexBlue);
165
166	return vertices;
167}
168
169deUint32 getFirstUsage (deUint32 attachmentIdx, const std::vector<SubpassParams>& subpasses)
170{
171	for (const auto& subpass : subpasses)
172		for (const auto& ref : subpass.attachmentRefs)
173			if (ref.idx == attachmentIdx)
174				return ref.usage;
175
176	return ATTACHMENT_USAGE_UNDEFINED;
177}
178
179std::string getFormatCaseName(VkFormat format)
180{
181	return de::toLower(de::toString(getFormatStr(format)).substr(10));
182}
183
184// Selects an image format based on the usage flags.
185VkFormat getFormat (deUint32 usage, VkFormat depthStencilFormat)
186{
187	if (usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
188	{
189		return depthStencilFormat;
190	}
191
192	if (usage & ATTACHMENT_USAGE_INTEGER)
193	{
194		// Color attachment using integer format.
195		return VK_FORMAT_R8G8B8A8_UINT;
196	}
197
198	return VK_FORMAT_R8G8B8A8_UNORM;
199}
200
201template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
202Move<VkRenderPass> createRenderPass (const DeviceInterface&	vk,
203									 VkDevice				vkDevice,
204									 const TestParams		testParams)
205{
206	const VkImageAspectFlags	aspectMask						= testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
207	std::vector<AttachmentDesc>	attachmentDescriptions;
208	std::vector<SubpassDesc>	subpassDescriptions;
209
210	struct Refs
211	{
212		std::vector<AttachmentRef>	colorAttachmentRefs;
213		std::vector<AttachmentRef>	resolveAttachmentRefs;
214		std::vector<AttachmentRef>	depthStencilAttachmentRefs;
215		std::vector<AttachmentRef>	inputAttachmentRefs;
216	};
217
218	std::vector<Refs>			subpassRefs;
219	bool						hasInputAttachment				= false;
220
221	for (size_t i = 0; i < testParams.attachments.size(); i++)
222	{
223		VkImageLayout	initialLayout;
224		VkImageLayout	finalLayout;
225		VkFormat		format			= getFormat(testParams.attachments[i].usage, testParams.depthStencilFormat);
226
227		// Search for the first reference to determine the initial layout.
228		deUint32 firstUsage = getFirstUsage((deUint32)i, testParams.subpasses);
229
230		// No subpasses using this attachment. Use the usage flags of the attachment.
231		if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
232			firstUsage = testParams.attachments[i].usage;
233
234		if (firstUsage & ATTACHMENT_USAGE_COLOR)
235			initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
236		else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
237			initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
238		else
239		{
240			DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT);
241			initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
242		}
243
244		// Set final layout to transfer src if it's being verified. Otherwise
245		// just use the initial layout as it's known to be supported by
246		// the usage flags.
247		if (!testParams.attachments[i].verifyAspects.empty())
248			finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
249		else
250			finalLayout = initialLayout;
251
252		const VkSampleCountFlagBits	sampleCount		= testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
253
254		const AttachmentDesc		attachmentDesc	=
255		{
256			DE_NULL,									// const void*						pNext
257			(VkAttachmentDescriptionFlags) 0,			// VkAttachmentDescriptionFlags		flags
258			format,										// VkFormat							format
259			sampleCount,								// VkSampleCountFlagBits			samples
260			testParams.attachments[i].loadOp,			// VkAttachmentLoadOp				loadOp
261			testParams.attachments[i].storeOp,			// VkAttachmentStoreOp				storeOp
262			testParams.attachments[i].stencilLoadOp,	// VkAttachmentLoadOp				stencilLoadOp
263			testParams.attachments[i].stencilStoreOp,	// VkAttachmentStoreOp				stencilStoreOp
264			initialLayout,								// VkImageLayout					initialLayout
265			finalLayout									// VkImageLayout					finalLayout
266		};
267
268		attachmentDescriptions.push_back(attachmentDesc);
269	}
270
271	for (const auto& subpass : testParams.subpasses)
272	{
273		subpassRefs.push_back({});
274		auto& refs = subpassRefs.back();
275
276		for (const auto& ref : subpass.attachmentRefs)
277		{
278			VkImageLayout layout;
279
280			if (ref.usage & ATTACHMENT_USAGE_RESOLVE_TARGET)
281			{
282				layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
283				refs.resolveAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
284			}
285			else if (ref.usage & ATTACHMENT_USAGE_COLOR)
286			{
287				layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
288				refs.colorAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
289			}
290			else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
291			{
292				layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
293				const auto depthStencilAspectMask = testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : getImageAspectFlags(mapVkFormat(testParams.depthStencilFormat));
294				refs.depthStencilAttachmentRefs.push_back({DE_NULL, ref.idx, layout, depthStencilAspectMask});
295			}
296			else
297			{
298				DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT);
299				layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
300				refs.inputAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
301				hasInputAttachment = true;
302			}
303		}
304
305		const SubpassDesc			subpassDescription			=
306		{
307			DE_NULL,
308			(VkSubpassDescriptionFlags)0,																// VkSubpassDescriptionFlags		flags
309			VK_PIPELINE_BIND_POINT_GRAPHICS,															// VkPipelineBindPoint				pipelineBindPoint
310			0u,																							// deUint32							viewMask
311			(deUint32)refs.inputAttachmentRefs.size(),													// deUint32							inputAttachmentCount
312			refs.inputAttachmentRefs.empty() ? DE_NULL : refs.inputAttachmentRefs.data(),				// const VkAttachmentReference*		pInputAttachments
313			(deUint32)refs.colorAttachmentRefs.size(),													// deUint32							colorAttachmentCount
314			refs.colorAttachmentRefs.empty() ? DE_NULL : refs.colorAttachmentRefs.data(),				// const VkAttachmentReference*		pColorAttachments
315			refs.resolveAttachmentRefs.empty() ? DE_NULL : refs.resolveAttachmentRefs.data(),			// const VkAttachmentReference*		pResolveAttachments
316			refs.depthStencilAttachmentRefs.empty() ? DE_NULL : refs.depthStencilAttachmentRefs.data(),	// const VkAttachmentReference*		pDepthStencilAttachment
317			0u,																							// deUint32							preserveAttachmentCount
318			DE_NULL																						// const deUint32*					pPreserveAttachments
319		};
320
321		subpassDescriptions.push_back(subpassDescription);
322	}
323
324	// Dependency of color attachment of subpass 0 to input attachment of subpass 1.
325	// Determined later if it's being used.
326	const SubpassDep			subpassDependency				=
327	{
328		DE_NULL,										// const void*				pNext
329		0u,												// uint32_t					srcSubpass
330		1u,												// uint32_t					dstSubpass
331		VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,	// VkPipelineStageFlags		srcStageMask
332		VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			// VkPipelineStageFlags		dstStageMask
333		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,			// VkAccessFlags			srcAccessMask
334		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			// VkAccessFlags			dstAccessMask
335		VK_DEPENDENCY_BY_REGION_BIT,					// VkDependencyFlags		dependencyFlags
336		0u												// deInt32					viewOffset
337	};
338
339	const RenderPassCreateInfo	renderPassInfo					=
340	{
341		DE_NULL,											// const void*						pNext
342		(VkRenderPassCreateFlags)0,							// VkRenderPassCreateFlags			flags
343		(deUint32)attachmentDescriptions.size(),			// deUint32							attachmentCount
344		attachmentDescriptions.data(),						// const VkAttachmentDescription*	pAttachments
345		(deUint32)subpassDescriptions.size(),				// deUint32							subpassCount
346		subpassDescriptions.data(),							// const VkSubpassDescription*		pSubpasses
347		hasInputAttachment ? 1u : 0u,						// deUint32							dependencyCount
348		hasInputAttachment ? &subpassDependency : DE_NULL,	// const VkSubpassDependency*		pDependencies
349		0u,													// deUint32							correlatedViewMaskCount
350		DE_NULL												// const deUint32*					pCorrelatedViewMasks
351	};
352
353	return renderPassInfo.createRenderPass(vk, vkDevice);
354}
355
356class LoadStoreOpNoneTest : public vkt::TestCase
357{
358public:
359							LoadStoreOpNoneTest		(tcu::TestContext&	testContext,
360													 const std::string&	name,
361													 const TestParams&	testParams);
362	virtual					~LoadStoreOpNoneTest	(void);
363	virtual void			initPrograms			(SourceCollections&	sourceCollections) const;
364	virtual void			checkSupport			(Context& context) const;
365	virtual TestInstance*	createInstance			(Context& context) const;
366private:
367	const TestParams		m_testParams;
368};
369
370class LoadStoreOpNoneTestInstance : public vkt::TestInstance
371{
372public:
373								LoadStoreOpNoneTestInstance		(Context&			context,
374																 const TestParams&	testParams);
375	virtual						~LoadStoreOpNoneTestInstance	(void);
376	virtual tcu::TestStatus		iterate							(void);
377
378	template<typename RenderpassSubpass>
379	void						createCommandBuffer				(const DeviceInterface&					vk,
380																 VkDevice								vkDevice,
381																 std::vector<Move<VkDescriptorSet>>&	descriptorSets,
382																 std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
383																 std::vector<Move<VkPipeline>>&			pipelines);
384	void						createCommandBuffer				(const DeviceInterface&					vk,
385																 VkDevice								vkDevice,
386																 std::vector<Move<VkImageView>>&		imageViews,
387																 std::vector<Move<VkDescriptorSet>>&	descriptorSets,
388																 std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
389																 std::vector<Move<VkPipeline>>&			pipelines);
390	void						drawCommands					(VkCommandBuffer						cmdBuffer,
391																 std::vector<Move<VkDescriptorSet>>&	descriptorSets,
392																 std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
393																 std::vector<Move<VkPipeline>>&			pipelines) const;
394
395private:
396	TestParams					m_testParams;
397
398	const tcu::UVec2			m_imageSize;
399	const tcu::UVec2			m_renderSize;
400
401	Move<VkDescriptorPool>		m_descriptorPool;
402	Move<VkRenderPass>			m_renderPass;
403	Move<VkFramebuffer>			m_framebuffer;
404
405	Move<VkBuffer>				m_vertexBuffer;
406	std::vector<Vertex4RGBA>	m_vertices;
407	de::MovePtr<Allocation>		m_vertexBufferAlloc;
408
409	Move<VkCommandPool>			m_cmdPool;
410	Move<VkCommandBuffer>		m_cmdBuffer;
411	Move<VkCommandBuffer>		m_secCmdBuffer;
412};
413
414LoadStoreOpNoneTest::LoadStoreOpNoneTest (tcu::TestContext&		testContext,
415										  const std::string&	name,
416										  const TestParams&		testParams)
417	: vkt::TestCase	(testContext, name)
418	, m_testParams(testParams)
419{
420}
421
422LoadStoreOpNoneTest::~LoadStoreOpNoneTest (void)
423{
424}
425
426TestInstance* LoadStoreOpNoneTest::createInstance (Context& context) const
427{
428	return new LoadStoreOpNoneTestInstance(context, m_testParams);
429}
430
431void LoadStoreOpNoneTest::checkSupport (Context& ctx) const
432{
433	// Check for renderpass2 extension if used.
434	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
435		ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2");
436
437	// Check for dynamic_rendering extension if used
438	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
439		ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
440
441	ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none");
442
443	// Check depth/stencil format support.
444	for (const auto& att : m_testParams.attachments)
445	{
446		if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
447		{
448			const VkFormat		format		= getFormat(att.usage, m_testParams.depthStencilFormat);
449			VkImageUsageFlags	usage		= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
450			const auto			aspectFlags	= getImageAspectFlags(mapVkFormat(format));
451
452			if (att.usage & ATTACHMENT_USAGE_DEPTH)
453				DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT) != 0u);
454
455			if (att.usage & ATTACHMENT_USAGE_STENCIL)
456				DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0u);
457
458			DE_UNREF(aspectFlags); // For release builds.
459
460			if (!att.verifyAspects.empty())
461				usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
462
463			if (att.init & ATTACHMENT_INIT_PRE)
464				usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
465
466			const auto&				vki			= ctx.getInstanceInterface();
467			const auto				physDev		= ctx.getPhysicalDevice();
468			const auto				imgType		= VK_IMAGE_TYPE_2D;
469			const auto				tiling		= VK_IMAGE_TILING_OPTIMAL;
470			VkImageFormatProperties	properties;
471			const auto				result		= vki.getPhysicalDeviceImageFormatProperties(physDev, format, imgType, tiling, usage, 0u, &properties);
472
473			if (result != VK_SUCCESS)
474				TCU_THROW(NotSupportedError, "Depth-stencil format not supported");
475		}
476	}
477}
478
479void LoadStoreOpNoneTest::initPrograms (SourceCollections& sourceCollections) const
480{
481	std::ostringstream fragmentSource;
482
483	sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
484		"#version 450\n"
485		"layout(location = 0) in highp vec4 position;\n"
486		"layout(location = 1) in highp vec4 color;\n"
487		"layout(location = 0) out highp vec4 vtxColor;\n"
488		"void main (void)\n"
489		"{\n"
490		"	gl_Position = position;\n"
491		"	vtxColor = color;\n"
492		"}\n");
493
494	sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
495		"#version 450\n"
496		"layout(location = 0) in highp vec4 vtxColor;\n"
497		"layout(location = 0) out highp vec4 fragColor;\n"
498		"void main (void)\n"
499		"{\n"
500		"	fragColor = vtxColor;\n"
501		"	gl_FragDepth = 1.0;\n"
502		"}\n");
503
504	sourceCollections.glslSources.add("color_frag_uint") << glu::FragmentSource(
505		"#version 450\n"
506		"layout(location = 0) in highp vec4 vtxColor;\n"
507		"layout(location = 0) out highp uvec4 fragColor;\n"
508		"void main (void)\n"
509		"{\n"
510		"	fragColor = uvec4(vtxColor * vec4(255));\n"
511		"	gl_FragDepth = 1.0;\n"
512		"}\n");
513
514	sourceCollections.glslSources.add("color_frag_blend") << glu::FragmentSource(
515		"#version 450\n"
516		"layout(location = 0) in highp vec4 vtxColor;\n"
517		"layout(location = 0) out highp vec4 fragColor;\n"
518		"void main (void)\n"
519		"{\n"
520		"	fragColor = vec4(vtxColor.rgb, 0.5);\n"
521		"	gl_FragDepth = 1.0;\n"
522		"}\n");
523
524	sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource(
525		"#version 450\n"
526		"layout(location = 0) in highp vec4 vtxColor;\n"
527		"layout(location = 0) out highp vec4 fragColor;\n"
528		"layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;\n"
529		"void main (void)\n"
530		"{\n"
531		"	fragColor = subpassLoad(inputColor) + vtxColor;\n"
532		"	gl_FragDepth = 1.0;\n"
533		"}\n");
534}
535
536LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance	(Context&			context,
537															 const TestParams&	testParams)
538	: vkt::TestInstance	(context)
539	, m_testParams		(testParams)
540	, m_imageSize		(32u, 32u)
541	, m_renderSize		(27u, 19u)
542	, m_vertices		(createQuad())
543{
544}
545
546LoadStoreOpNoneTestInstance::~LoadStoreOpNoneTestInstance (void)
547{
548}
549
550template<typename RenderpassSubpass>
551void LoadStoreOpNoneTestInstance::createCommandBuffer	(const DeviceInterface&					vk,
552														 VkDevice								vkDevice,
553														 std::vector<Move<VkDescriptorSet>>&	descriptorSets,
554														 std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
555														 std::vector<Move<VkPipeline>>&			pipelines)
556{
557	const typename RenderpassSubpass::SubpassBeginInfo	subpassBeginInfo	(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
558	const typename RenderpassSubpass::SubpassEndInfo	subpassEndInfo		(DE_NULL);
559
560	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
561
562	beginCommandBuffer(vk, *m_cmdBuffer, 0u);
563	const VkRenderPassBeginInfo renderPassBeginInfo
564	{
565		VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,	// VkStructureType		sType
566		DE_NULL,									// const void*			pNext
567		*m_renderPass,								// VkRenderPass			renderPass
568		*m_framebuffer,								// VkFramebuffer		framebuffer
569		makeRect2D(m_renderSize),					// VkRect2D				renderArea
570		0u,											// uint32_t				clearValueCount
571		DE_NULL										// const VkClearValue*	pClearValues
572	};
573	RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
574
575	drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
576
577	RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
578	endCommandBuffer(vk, *m_cmdBuffer);
579}
580
581void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface&				vk,
582													  VkDevice								vkDevice,
583													  std::vector<Move<VkImageView>>&		imageViews,
584													  std::vector<Move<VkDescriptorSet>>&	descriptorSets,
585													  std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
586													  std::vector<Move<VkPipeline>>&		pipelines)
587{
588	std::vector<VkRenderingAttachmentInfoKHR>	colorAttachments;
589
590	VkRenderingAttachmentInfoKHR				depthAttachment
591	{
592		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,				// VkStructureType						sType;
593		DE_NULL,														// const void*							pNext;
594		DE_NULL,														// VkImageView							imageView;
595		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
596		VK_RESOLVE_MODE_NONE,											// VkResolveModeFlagBits				resolveMode;
597		DE_NULL,														// VkImageView							resolveImageView;
598		VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout						resolveImageLayout;
599		VK_ATTACHMENT_LOAD_OP_LOAD,										// VkAttachmentLoadOp					loadOp;
600		VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp					storeOp;
601		makeClearValueDepthStencil(0.0f, 0u)							// VkClearValue							clearValue;
602	};
603
604	VkRenderingAttachmentInfoKHR				stencilAttachment
605	{
606		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,				// VkStructureType						sType;
607		DE_NULL,														// const void*							pNext;
608		DE_NULL,														// VkImageView							imageView;
609		VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
610		VK_RESOLVE_MODE_NONE,											// VkResolveModeFlagBits				resolveMode;
611		DE_NULL,														// VkImageView							resolveImageView;
612		VK_IMAGE_LAYOUT_UNDEFINED,										// VkImageLayout						resolveImageLayout;
613		VK_ATTACHMENT_LOAD_OP_LOAD,										// VkAttachmentLoadOp					loadOp;
614		VK_ATTACHMENT_STORE_OP_STORE,									// VkAttachmentStoreOp					storeOp;
615		makeClearValueDepthStencil(0.0f, 0u)							// VkClearValue							clearValue;
616	};
617
618	bool useDepth		= false;
619	bool useStencil		= false;
620
621	VkSampleCountFlagBits	sampleCount = VK_SAMPLE_COUNT_1_BIT;
622	std::vector<VkFormat>	colorAttachmentFormats;
623
624	for (size_t i = 0; i < imageViews.size(); i++)
625	{
626		if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE)
627		{
628			DE_ASSERT(m_testParams.attachments[i + 1].usage & ATTACHMENT_USAGE_RESOLVE_TARGET);
629			const auto resolveMode = ((m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INTEGER) ? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT : VK_RESOLVE_MODE_AVERAGE_BIT);
630			colorAttachments.push_back({
631				VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,		// VkStructureType						sType;
632				DE_NULL,												// const void*							pNext;
633				*imageViews[i],											// VkImageView							imageView;
634				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
635				resolveMode,											// VkResolveModeFlagBits				resolveMode;
636				*imageViews[i + 1],										// VkImageView							resolveImageView;
637				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout						resolveImageLayout;
638				m_testParams.attachments[i].loadOp,						// VkAttachmentLoadOp					loadOp;
639				m_testParams.attachments[i].storeOp,					// VkAttachmentStoreOp					storeOp;
640				makeClearValueColor(tcu::Vec4(0.0f))					// VkClearValue							clearValue;
641				});
642			colorAttachmentFormats.push_back(getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
643			sampleCount = VK_SAMPLE_COUNT_4_BIT;
644			i += 1;
645		}
646		else if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_COLOR)
647		{
648			colorAttachments.push_back({
649				VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,		// VkStructureType						sType;
650				DE_NULL,												// const void*							pNext;
651				*imageViews[i],											// VkImageView							imageView;
652				VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout						imageLayout;
653				VK_RESOLVE_MODE_NONE,									// VkResolveModeFlagBits				resolveMode;
654				DE_NULL,												// VkImageView							resolveImageView;
655				VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout						resolveImageLayout;
656				m_testParams.attachments[i].loadOp,						// VkAttachmentLoadOp					loadOp;
657				m_testParams.attachments[i].storeOp,					// VkAttachmentStoreOp					storeOp;
658				makeClearValueColor(tcu::Vec4(0.0f))					// VkClearValue							clearValue;
659				});
660			colorAttachmentFormats.push_back(getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
661		}
662		else
663		{
664			deUint32	  usage = m_testParams.attachments[i].usage;
665			useDepth	= usage & ATTACHMENT_USAGE_DEPTH;
666			useStencil	= usage & ATTACHMENT_USAGE_STENCIL;
667
668			depthAttachment.imageView	= *imageViews[i];
669			depthAttachment.loadOp		= m_testParams.attachments[i].loadOp;
670			depthAttachment.storeOp		= m_testParams.attachments[i].storeOp;
671			stencilAttachment.imageView	= *imageViews[i];
672			stencilAttachment.loadOp	= m_testParams.attachments[i].stencilLoadOp;
673			stencilAttachment.storeOp	= m_testParams.attachments[i].stencilStoreOp;
674		}
675	}
676
677	VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
678	{
679		VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR,		// VkStructureType					sType;
680		DE_NULL,																// const void*						pNext;
681		0u,																		// VkRenderingFlagsKHR				flags;
682		0u,																		// uint32_t							viewMask;
683		static_cast<deUint32>(colorAttachmentFormats.size()),					// uint32_t							colorAttachmentCount;
684		colorAttachmentFormats.data(),											// const VkFormat*					pColorAttachmentFormats;
685		useDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							depthAttachmentFormat;
686		useStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED,		// VkFormat							stencilAttachmentFormat;
687		sampleCount																// VkSampleCountFlagBits			rasterizationSamples;
688	};
689
690	const VkCommandBufferInheritanceInfo	bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
691	VkCommandBufferBeginInfo				commandBufBeginParams
692	{
693		VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,							// VkStructureType					sType;
694		DE_NULL,																// const void*						pNext;
695		VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,							// VkCommandBufferUsageFlags		flags;
696		&bufferInheritanceInfo
697	};
698
699	VkRenderingInfoKHR renderingInfo
700	{
701		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
702		DE_NULL,
703		0u,																// VkRenderingFlagsKHR					flags;
704		makeRect2D(m_renderSize),										// VkRect2D								renderArea;
705		1u,																// deUint32								layerCount;
706		0u,																// deUint32								viewMask;
707		(deUint32)colorAttachments.size(),								// deUint32								colorAttachmentCount;
708		de::dataOrNull(colorAttachments),								// const VkRenderingAttachmentInfoKHR*	pColorAttachments;
709		useDepth ? &depthAttachment : DE_NULL,							// const VkRenderingAttachmentInfoKHR*	pDepthAttachment;
710		useStencil ? &stencilAttachment : DE_NULL						// const VkRenderingAttachmentInfoKHR*	pStencilAttachment;
711	};
712
713	m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
714
715	if (m_testParams.groupParams->useSecondaryCmdBuffer)
716	{
717		m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
718
719		// record secondary command buffer
720		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
721		{
722			inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
723			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
724			vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
725		}
726		else
727		{
728			commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
729			vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
730		}
731
732		drawCommands(*m_secCmdBuffer, descriptorSets, pipelineLayouts, pipelines);
733
734		if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
735			vk.cmdEndRendering(*m_secCmdBuffer);
736		endCommandBuffer(vk, *m_secCmdBuffer);
737
738		// record primary command buffer
739		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
740		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
741		{
742			renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
743			vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
744		}
745		vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
746		if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
747			vk.cmdEndRendering(*m_cmdBuffer);
748		endCommandBuffer(vk, *m_cmdBuffer);
749	}
750	else
751	{
752		beginCommandBuffer(vk, *m_cmdBuffer, 0u);
753		vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
754
755		drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
756
757		vk.cmdEndRendering(*m_cmdBuffer);
758		endCommandBuffer(vk, *m_cmdBuffer);
759	}
760}
761
762void LoadStoreOpNoneTestInstance::drawCommands(VkCommandBuffer						cmdBuffer,
763											   std::vector<Move<VkDescriptorSet>>&	descriptorSets,
764											   std::vector<Move<VkPipelineLayout>>&	pipelineLayouts,
765											   std::vector<Move<VkPipeline>>&		pipelines) const
766{
767	const DeviceInterface&	vk					= m_context.getDeviceInterface();
768	const VkClearRect		rect				= { makeRect2D(m_renderSize), 0u, 1u };
769	const VkDeviceSize		vertexBufferOffset	= 0;
770
771	// Add clear commands for selected attachments
772	std::vector<VkClearAttachment> clearAttachments;
773	deUint32 colorAttIdx = 0u;
774	for (const auto& att : m_testParams.attachments)
775	{
776		if (att.init & ATTACHMENT_INIT_CMD_CLEAR)
777		{
778			if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
779			{
780				VkImageAspectFlags	aspectMask = 0;
781				if (att.usage & ATTACHMENT_USAGE_DEPTH) aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
782				if (att.usage & ATTACHMENT_USAGE_STENCIL) aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
783				clearAttachments.push_back({ aspectMask, 0u, makeClearValueDepthStencil(0.25, 64) });
784			}
785			else
786			{
787				clearAttachments.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++,
788											makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f) });
789			}
790		}
791	}
792	if (!clearAttachments.empty())
793		vk.cmdClearAttachments(cmdBuffer, (deUint32)clearAttachments.size(), clearAttachments.data(), 1u, &rect);
794
795	vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
796
797	deUint32	descriptorSetIdx	= 0u;
798	deUint32	vertexOffset		= 0u;
799	for (size_t i = 0; i < m_testParams.subpasses.size(); i++)
800	{
801		if (i != 0)
802		{
803			// multi subpass tests should not be executed for dynamic rendering
804			DE_ASSERT(m_testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING);
805			vk.cmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
806		}
807
808		vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[i]);
809
810		bool hasInput = false;
811		for (const auto& ref : m_testParams.subpasses[i].attachmentRefs)
812			if (ref.usage & ATTACHMENT_USAGE_INPUT)
813				hasInput = true;
814
815		if (hasInput)
816			vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1,
817									 &descriptorSets[descriptorSetIdx++].get(), 0, DE_NULL);
818
819		for (deUint32 d = 0; d < m_testParams.subpasses[i].numDraws; d++)
820		{
821			vk.cmdDraw(cmdBuffer, 6u, 1, vertexOffset, 0);
822			vertexOffset += 6u;
823		}
824	}
825}
826
827tcu::TestStatus LoadStoreOpNoneTestInstance::iterate (void)
828{
829	const DeviceInterface&					vk						= m_context.getDeviceInterface();
830	const VkDevice							vkDevice				= m_context.getDevice();
831	const VkQueue							queue					= m_context.getUniversalQueue();
832	const deUint32							queueFamilyIndex		= m_context.getUniversalQueueFamilyIndex();
833	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
834	const VkComponentMapping				componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
835	bool									depthIsUndefined		= false;
836	bool									stencilIsUndefined		= false;
837
838	std::vector<Move<VkImage>>				attachmentImages;
839	std::vector<de::MovePtr<Allocation>>	attachmentImageAllocs;
840	std::vector<Move<VkImageView>>			imageViews;
841	std::vector<Move<VkPipeline>>			pipelines;
842
843	for (const auto& att : m_testParams.attachments)
844	{
845		VkFormat				format				= getFormat(att.usage, m_testParams.depthStencilFormat);
846		VkImageUsageFlags		usage				= 0;
847		VkImageAspectFlags		aspectFlags;
848
849		if (!att.verifyAspects.empty()) usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
850		if (att.init & ATTACHMENT_INIT_PRE) usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
851
852		if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
853		{
854			aspectFlags = getImageAspectFlags(mapVkFormat(format));
855			usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
856
857			// If depth or stencil load op is NONE, "the previous contents of the image will be undefined inside the render pass. No
858			// access type is used as the image is not accessed."
859			if (att.loadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
860				depthIsUndefined = true;
861
862			if (att.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
863				stencilIsUndefined = true;
864		}
865		else
866		{
867			// Color and input attachments.
868			aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
869
870			if (att.usage & ATTACHMENT_USAGE_COLOR)
871				usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
872			if (att.usage & ATTACHMENT_USAGE_INPUT)
873				usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
874		}
875
876		const VkSampleCountFlagBits	sampleCount		= att.usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
877
878		const VkImageCreateInfo		imageParams		=
879		{
880			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			sType
881			DE_NULL,									// const void*				pNext
882			0u,											// VkImageCreateFlags		flags
883			VK_IMAGE_TYPE_2D,							// VkImageType				imageType
884			format,										// VkFormat					format
885			{ m_imageSize.x(), m_imageSize.y(), 1u },	// VkExtent3D				extent
886			1u,											// deUint32					mipLevels
887			1u,											// deUint32					arrayLayers
888			sampleCount,								// VkSampleCountFlagBits	samples
889			VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling
890			usage,										// VkImageUsageFlags		usage
891			VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode
892			1u,											// deUint32					queueFamilyIndexCount
893			&queueFamilyIndex,							// const deUint32*			pQueueFamilyIndices
894			VK_IMAGE_LAYOUT_UNDEFINED					// VkImageLayout			initialLayout
895		};
896
897		attachmentImages.push_back(createImage(vk, vkDevice, &imageParams));
898
899		// Allocate and bind image memory.
900		attachmentImageAllocs.push_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any));
901		VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(), attachmentImageAllocs.back()->getOffset()));
902
903		// Create image view.
904		const VkImageViewCreateInfo	imageViewParams	=
905		{
906			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType
907			DE_NULL,									// const void*				pNext
908			0u,											// VkImageViewCreateFlags	flags
909			*attachmentImages.back(),					// VkImage					image
910			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType
911			format,										// VkFormat					format
912			componentMappingRGBA,						// VkChannelMapping			channels
913			{ aspectFlags, 0u, 1u, 0u, 1u }				// VkImageSubresourceRange	subresourceRange
914		};
915
916		imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams));
917
918		if (att.init & ATTACHMENT_INIT_PRE)
919		{
920			// Preinitialize image
921			deUint32 firstUsage = getFirstUsage((deUint32)attachmentImages.size() - 1, m_testParams.subpasses);
922			if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
923				firstUsage = att.usage;
924
925			if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
926			{
927				const auto dstAccess	= (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
928				const auto dstStage		= (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
929
930				clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), format, 0.5f, 128u,
931									   VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
932									   dstAccess, dstStage);
933			}
934			else
935			{
936				const auto dstAccess	= (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
937				const auto dstStage		= (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
938				const auto clearColor	= ((att.usage & ATTACHMENT_USAGE_INTEGER) ? makeClearValueColorU32(0u, 255u, 0u, 255u).color : makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f).color);
939				const auto layout		= ((firstUsage & ATTACHMENT_USAGE_COLOR) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
940
941				clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), clearColor, VK_IMAGE_LAYOUT_UNDEFINED,
942								layout, dstAccess, dstStage);
943			}
944		}
945	}
946
947	if (m_testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
948	{
949		// Create render pass.
950		if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
951			m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, m_testParams);
952		else
953			m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, m_testParams);
954
955		std::vector<VkImageView> views;
956		for (const auto& view : imageViews)
957			views.push_back(*view);
958
959		// Create framebuffer.
960		const VkFramebufferCreateInfo	framebufferParams	=
961		{
962			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType
963			DE_NULL,									// const void*				pNext
964			0u,											// VkFramebufferCreateFlags	flags
965			*m_renderPass,								// VkRenderPass				renderPass
966			(deUint32)views.size(),						// deUint32					attachmentCount
967			views.data(),								// const VkImageView*		pAttachments
968			(deUint32)m_imageSize.x(),					// deUint32					width
969			(deUint32)m_imageSize.y(),					// deUint32					height
970			1u											// deUint32					layers
971		};
972
973		m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
974	}
975
976	// Create shader modules
977	Unique<VkShaderModule>		vertexShaderModule			(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0));
978	Unique<VkShaderModule>		fragmentShaderModule		(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0));
979	Unique<VkShaderModule>		fragmentShaderModuleUint	(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_uint"), 0));
980	Unique<VkShaderModule>		fragmentShaderModuleBlend	(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0));
981	Unique<VkShaderModule>		fragmentShaderModuleInput	(createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0));
982
983	// Create descriptor pool. Prepare for using one input attachment at most.
984	{
985		const VkDescriptorPoolSize			descriptorPoolSize			=
986		{
987			VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		type
988			1u										// deUint32				descriptorCount
989		};
990
991		const VkDescriptorPoolCreateInfo	descriptorPoolCreateInfo	=
992		{
993			VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,		// VkStructureType				sType
994			DE_NULL,											// const void*					pNext
995			VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,	// VkDescriptorPoolCreateFlags	flags
996			1u,													// deUint32						maxSets
997			1u,													// deUint32						poolSizeCount
998			&descriptorPoolSize									// const VkDescriptorPoolSize*	pPoolSizes
999		};
1000
1001		m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
1002	}
1003
1004	std::vector<Move<VkDescriptorSetLayout>>		descriptorSetLayouts;
1005	std::vector<Move<VkDescriptorSet>>				descriptorSets;
1006	std::vector<Move<VkPipelineLayout>>				pipelineLayouts;
1007
1008	for (const auto& subpass : m_testParams.subpasses)
1009	{
1010		deUint32	numInputAttachments	= 0u;
1011		bool		noColorWrite		= false;
1012		bool		depthTest			= false;
1013		bool		stencilTest			= false;
1014		bool		depthWrite			= true;
1015		bool		stencilWrite		= true;
1016		bool		multisample			= false;
1017		bool		uintColorBuffer		= false;
1018		VkCompareOp	depthCompareOp		= VK_COMPARE_OP_GREATER;
1019		VkCompareOp	stencilCompareOp	= VK_COMPARE_OP_GREATER;
1020
1021		// Create pipeline layout.
1022		{
1023			std::vector<VkDescriptorSetLayoutBinding>	layoutBindings;
1024
1025			for (const auto ref : subpass.attachmentRefs)
1026			{
1027				if (ref.usage & ATTACHMENT_USAGE_INPUT)
1028				{
1029					const VkDescriptorSetLayoutBinding	layoutBinding	=
1030					{
1031						0u,										// deUint32				binding
1032						VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType		descriptorType
1033						1u,										// deUint32				descriptorCount
1034						VK_SHADER_STAGE_FRAGMENT_BIT,			// VkShaderStageFlags	stageFlags
1035						DE_NULL									// const VkSampler*		pImmutableSamplers
1036					};
1037
1038					layoutBindings.push_back(layoutBinding);
1039					numInputAttachments++;
1040				}
1041				if (ref.usage & ATTACHMENT_USAGE_COLOR)
1042				{
1043					if (ref.usage & ATTACHMENT_USAGE_COLOR_WRITE_OFF)
1044						noColorWrite = true;
1045				}
1046				if (ref.usage & ATTACHMENT_USAGE_DEPTH)
1047				{
1048					if (!(ref.usage & ATTACHMENT_USAGE_DEPTH_TEST_OFF))
1049						depthTest = true;
1050					if (ref.usage & ATTACHMENT_USAGE_DEPTH_WRITE_OFF)
1051						depthWrite = false;
1052
1053					// Enabling depth testing with undefined depth buffer contents. Let's make sure
1054					// all samples pass the depth test.
1055					if (depthIsUndefined && depthTest)
1056						depthCompareOp = VK_COMPARE_OP_ALWAYS;
1057				}
1058				if (ref.usage & ATTACHMENT_USAGE_STENCIL)
1059				{
1060					if (!(ref.usage & ATTACHMENT_USAGE_STENCIL_TEST_OFF))
1061						stencilTest = true;
1062					if (ref.usage & ATTACHMENT_USAGE_STENCIL_WRITE_OFF)
1063						stencilWrite = false;
1064
1065					if (stencilIsUndefined && stencilTest)
1066						stencilCompareOp = VK_COMPARE_OP_ALWAYS;
1067				}
1068				if (ref.usage & ATTACHMENT_USAGE_MULTISAMPLE)
1069				{
1070					multisample = true;
1071				}
1072				if (ref.usage & ATTACHMENT_USAGE_INTEGER)
1073				{
1074					uintColorBuffer = true;
1075				}
1076			}
1077
1078			const VkDescriptorSetLayoutCreateInfo		descriptorSetLayoutParams	=
1079			{
1080				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,		// VkStructureType						sType
1081				DE_NULL,													// const void*							pNext
1082				0u,															// VkDescriptorSetLayoutCreateFlags		flags
1083				(deUint32) layoutBindings.size(),							// deUint32								bindingCount
1084				layoutBindings.empty() ? DE_NULL : layoutBindings.data()	// const VkDescriptorSetLayoutBinding*	pBindings
1085			};
1086			descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams));
1087
1088			const VkPipelineLayoutCreateInfo			pipelineLayoutParams		=
1089			{
1090				VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// VkStructureType				sType
1091				DE_NULL,										// const void*					pNext
1092				0u,												// VkPipelineLayoutCreateFlags	flags
1093				1u,												// deUint32						setLayoutCount
1094				&descriptorSetLayouts.back().get(),				// const VkDescriptorSetLayout*	pSetLayouts
1095				0u,												// deUint32						pushConstantRangeCount
1096				DE_NULL											// const VkPushConstantRange*	pPushConstantRanges
1097			};
1098
1099			pipelineLayouts.push_back(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
1100		}
1101
1102		// Update descriptor set if needed.
1103		if (numInputAttachments > 0u)
1104		{
1105			// Assuming there's only one input attachment at most.
1106			DE_ASSERT(numInputAttachments == 1u);
1107
1108			const VkDescriptorSetAllocateInfo	descriptorSetAllocateInfo	=
1109			{
1110				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,	// VkStructureType				sType
1111				DE_NULL,										// const void*					pNext
1112				*m_descriptorPool,								// VkDescriptorPool				descriptorPool
1113				1u,												// deUint32						descriptorSetCount
1114				&descriptorSetLayouts.back().get(),				// const VkDescriptorSetLayout*	pSetLayouts
1115			};
1116
1117			descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo));
1118
1119			for (size_t i = 0; i < imageViews.size(); i++)
1120			{
1121				if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
1122				{
1123					const VkDescriptorImageInfo	inputImageInfo	=
1124					{
1125						DE_NULL,									// VkSampler		sampler
1126						*imageViews[i],								// VkImageView		imageView
1127						VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL	// VkImageLayout	imageLayout
1128					};
1129
1130					const VkWriteDescriptorSet	descriptorWrite	=
1131					{
1132						VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,	// VkStructureType					sType
1133						DE_NULL,								// const void*						pNext
1134						*descriptorSets.back(),					// VkDescriptorSet					dstSet
1135						0u,										// deUint32							dstBinding
1136						0u,										// deUint32							dstArrayElement
1137						1u,										// deUint32							descriptorCount
1138						VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,	// VkDescriptorType					descriptorType
1139						&inputImageInfo,						// const VkDescriptorImageInfo*		pImageInfo
1140						DE_NULL,								// const VkDescriptorBufferInfo*	pBufferInfo
1141						DE_NULL									// const VkBufferView*				pTexelBufferView
1142					};
1143					vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
1144				}
1145			}
1146		}
1147
1148		// Create pipeline.
1149		{
1150			const VkVertexInputBindingDescription		vertexInputBindingDescription		=
1151			{
1152				0u,								// deUint32					binding
1153				(deUint32)sizeof(Vertex4RGBA),	// deUint32					strideInBytes
1154				VK_VERTEX_INPUT_RATE_VERTEX		// VkVertexInputStepRate	inputRate
1155			};
1156
1157			const VkVertexInputAttributeDescription		vertexInputAttributeDescriptions[2]	=
1158			{
1159				{
1160					0u,								// deUint32	location
1161					0u,								// deUint32	binding
1162					VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
1163					0u								// deUint32	offset
1164				},
1165				{
1166					1u,								// deUint32	location
1167					0u,								// deUint32	binding
1168					VK_FORMAT_R32G32B32A32_SFLOAT,	// VkFormat	format
1169					(deUint32)(sizeof(float) * 4),	// deUint32	offset
1170				}
1171			};
1172
1173			const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams				=
1174			{
1175				VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType							sType
1176				DE_NULL,													// const void*								pNext
1177				0u,															// VkPipelineVertexInputStateCreateFlags	flags
1178				1u,															// deUint32									vertexBindingDescriptionCount
1179				&vertexInputBindingDescription,								// const VkVertexInputBindingDescription*	pVertexBindingDescriptions
1180				2u,															// deUint32									vertexAttributeDescriptionCount
1181				vertexInputAttributeDescriptions							// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions
1182			};
1183
1184			const VkColorComponentFlags					writeMask							= noColorWrite ? 0 : VK_COLOR_COMPONENT_R_BIT	// VkColorComponentFlags	colorWriteMask
1185																											   | VK_COLOR_COMPONENT_G_BIT
1186																											   | VK_COLOR_COMPONENT_B_BIT
1187																											   | VK_COLOR_COMPONENT_A_BIT;
1188
1189			const VkPipelineColorBlendAttachmentState	colorBlendAttachmentState			=
1190			{
1191				m_testParams.alphaBlend,				// VkBool32					blendEnable
1192				VK_BLEND_FACTOR_SRC_ALPHA,				// VkBlendFactor			srcColorBlendFactor
1193				VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,	// VkBlendFactor			dstColorBlendFactor
1194				VK_BLEND_OP_ADD,						// VkBlendOp				colorBlendOp
1195				VK_BLEND_FACTOR_ONE,					// VkBlendFactor			srcAlphaBlendFactor
1196				VK_BLEND_FACTOR_ZERO,					// VkBlendFactor			dstAlphaBlendFactor
1197				VK_BLEND_OP_ADD,						// VkBlendOp				alphaBlendOp
1198				writeMask								// VkColorComponentFlags	colorWriteMask
1199			};
1200
1201			const VkPipelineColorBlendStateCreateInfo	colorBlendStateParams				=
1202			{
1203				VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType
1204				DE_NULL,													// const void*									pNext
1205				0u,															// VkPipelineColorBlendStateCreateFlags			flags
1206				VK_FALSE,													// VkBool32										logicOpEnable
1207				VK_LOGIC_OP_CLEAR,											// VkLogicOp									logicOp
1208				1u,															// deUint32										attachmentCount
1209				&colorBlendAttachmentState,									// const VkPipelineColorBlendAttachmentState*	pAttachments
1210				{ 0.0f, 0.0f, 0.0f, 0.0f }									// float										blendConstants[4]
1211			};
1212
1213			const VkStencilOpState							stencilOpState					=
1214			{
1215				VK_STENCIL_OP_KEEP,											// VkStencilOp	failOp
1216				stencilWrite ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP,	// VkStencilOp	passOp
1217				VK_STENCIL_OP_KEEP,											// VkStencilOp	depthFailOp
1218				stencilCompareOp,											// VkCompareOp	compareOp
1219				0xff,														// deUint32		compareMask
1220				0xff,														// deUint32		writeMask
1221				0xff														// deUint32		reference
1222			};
1223
1224			const VkPipelineDepthStencilStateCreateInfo		depthStencilStateParams			=
1225			{
1226				VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType
1227				DE_NULL,													// const void*								pNext
1228				0u,															// VkPipelineDepthStencilStateCreateFlags	flags
1229				depthTest,													// VkBool32									depthTestEnable
1230				depthWrite ? VK_TRUE : VK_FALSE,							// VkBool32									depthWriteEnable
1231				depthCompareOp,												// VkCompareOp								depthCompareOp
1232				VK_FALSE,													// VkBool32									depthBoundsTestEnable
1233				stencilTest,												// VkBool32									stencilTestEnable
1234				stencilOpState,												// VkStencilOpState							front
1235				stencilOpState,												// VkStencilOpState							back
1236				0.0f,														// float									minDepthBounds
1237				1.0f,														// float									maxDepthBounds
1238			};
1239
1240			const VkPipelineMultisampleStateCreateInfo		multisampleStateParams			=
1241			{
1242					VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,		// VkStructureType							sType
1243					DE_NULL,														// const void*								pNext
1244					0u,																// VkPipelineMultisampleStateCreateFlags	flags
1245					multisample ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT,	// VkSampleCountFlagBits					rasterizationSamples
1246					VK_FALSE,														// VkBool32									sampleShadingEnable
1247					1.0f,															// float									minSampleShading
1248					DE_NULL,														// const VkSampleMask*						pSampleMask
1249					VK_FALSE,														// VkBool32									alphaToCoverageEnable
1250					VK_FALSE														// VkBool32									alphaToOneEnable
1251			};
1252
1253			const std::vector<VkViewport>					viewports						(1, makeViewport(m_imageSize));
1254			const std::vector<VkRect2D>						scissors						(1, makeRect2D(m_renderSize));
1255			VkShaderModule									fragShader						= *fragmentShaderModule;
1256
1257			if (numInputAttachments > 0u)
1258				fragShader = *fragmentShaderModuleInput;
1259			else if (uintColorBuffer)
1260				fragShader = *fragmentShaderModuleUint;
1261			else if (m_testParams.alphaBlend)
1262				fragShader = *fragmentShaderModuleBlend;
1263
1264			VkPipelineRenderingCreateInfoKHR renderingCreateInfo
1265			{
1266				VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
1267				DE_NULL,
1268				0u,
1269				0u,
1270				DE_NULL,
1271				VK_FORMAT_UNDEFINED,
1272				VK_FORMAT_UNDEFINED
1273			};
1274
1275			std::vector<VkFormat> colorVector;
1276			for (const auto& att : m_testParams.attachments)
1277			{
1278				VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat);
1279
1280				if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
1281				{
1282					const auto tcuFormat	= mapVkFormat(format);
1283					const auto hasDepth		= tcu::hasDepthComponent(tcuFormat.order);
1284					const auto hasStencil	= tcu::hasStencilComponent(tcuFormat.order);
1285					const auto useDepth		= att.usage & ATTACHMENT_USAGE_DEPTH;
1286					const auto useStencil	= att.usage & ATTACHMENT_USAGE_STENCIL;
1287					renderingCreateInfo.depthAttachmentFormat	= (hasDepth && useDepth		? format : VK_FORMAT_UNDEFINED);
1288					renderingCreateInfo.stencilAttachmentFormat	= (hasStencil && useStencil ? format : VK_FORMAT_UNDEFINED);
1289				}
1290				else if (!(att.usage & ATTACHMENT_USAGE_RESOLVE_TARGET))
1291				{
1292					colorVector.push_back(format);
1293				}
1294			}
1295
1296			vk::VkPipelineRenderingCreateInfoKHR* nextPtr = DE_NULL;
1297			if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
1298			{
1299				renderingCreateInfo.colorAttachmentCount	= static_cast<deUint32>(colorVector.size());
1300				renderingCreateInfo.pColorAttachmentFormats = colorVector.data();
1301
1302				nextPtr = &renderingCreateInfo;
1303			}
1304
1305			pipelines.push_back(makeGraphicsPipeline(
1306				vk,										// const DeviceInterface&							vk
1307				vkDevice,								// const VkDevice									device
1308				*pipelineLayouts.back(),				// const VkPipelineLayout							pipelineLayout
1309				*vertexShaderModule,					// const VkShaderModule								vertexShaderModule
1310				DE_NULL,								// const VkShaderModule								tessellationControlModule
1311				DE_NULL,								// const VkShaderModule								tessellationEvalModule
1312				DE_NULL,								// const VkShaderModule								geometryShaderModule
1313				fragShader,								// const VkShaderModule								fragmentShaderModule
1314				*m_renderPass,							// const VkRenderPass								renderPass
1315				viewports,								// const std::vector<VkViewport>&					viewports
1316				scissors,								// const std::vector<VkRect2D>&						scissors
1317				VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,	// const VkPrimitiveTopology						topology
1318				(deUint32)pipelines.size(),				// const deUint32									subpass
1319				0u,										// const deUint32									patchControlPoints
1320				&vertexInputStateParams,				// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
1321				DE_NULL,								// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
1322				&multisampleStateParams,				// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1323				&depthStencilStateParams,				// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo
1324				&colorBlendStateParams,					// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo
1325				DE_NULL,								// const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfo
1326				nextPtr));								// const void*										pNext
1327		}
1328	}
1329
1330	// Create vertex buffer.
1331	{
1332		const VkBufferCreateInfo	vertexBufferParams	=
1333		{
1334			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,						// VkStructureType		sType
1335			DE_NULL,													// const void*			pNext
1336			0u,															// VkBufferCreateFlags	flags
1337			(VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()),	// VkDeviceSize			size
1338			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,							// VkBufferUsageFlags	usage
1339			VK_SHARING_MODE_EXCLUSIVE,									// VkSharingMode		sharingMode
1340			1u,															// deUint32				queueFamilyIndexCount
1341			&queueFamilyIndex											// const deUint32*		pQueueFamilyIndices
1342		};
1343
1344		m_vertexBuffer		= createBuffer(vk, vkDevice, &vertexBufferParams);
1345		m_vertexBufferAlloc	= memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1346
1347		VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1348
1349		// Upload vertex data.
1350		deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1351		flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1352	}
1353
1354	// Create command pool.
1355	m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1356
1357	// Create command buffer.
1358	if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1359		createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1360	else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
1361		createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1362	else
1363		createCommandBuffer(vk, vkDevice, imageViews, descriptorSets, pipelineLayouts, pipelines);
1364
1365	// Submit commands.
1366	submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1367
1368	bool pass = true;
1369
1370	// Verify selected attachments.
1371	for (size_t i = 0; i < m_testParams.attachments.size(); i++)
1372	{
1373		bool transitioned = false;
1374		for (const auto& verify : m_testParams.attachments[i].verifyAspects)
1375		{
1376			de::MovePtr<tcu::TextureLevel>		textureLevelResult;
1377
1378			SimpleAllocator						allocator			(vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1379			VkFormat							format				= getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat);
1380
1381			if (verify.aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1382			{
1383				VkImageLayout layout = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1384				textureLevelResult = pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], m_testParams.depthStencilFormat, m_imageSize, layout);
1385				transitioned = true;
1386			}
1387			else if (verify.aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1388			{
1389				VkImageLayout layout = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1390				textureLevelResult = pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], m_testParams.depthStencilFormat, m_imageSize, layout);
1391				transitioned = true;
1392			}
1393			else
1394			{
1395				DE_ASSERT(verify.aspect == VK_IMAGE_ASPECT_COLOR_BIT);
1396				VkImageLayout layout = ((m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && !transitioned) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1397				textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], format, m_imageSize, layout);
1398				transitioned = true;
1399			}
1400
1401			const tcu::ConstPixelBufferAccess&	access				= textureLevelResult->getAccess();
1402
1403			// Log attachment contents
1404			m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
1405												<< tcu::TestLog::Image("Attachment " + de::toString(i), "", access)
1406												<< tcu::TestLog::EndImageSet;
1407
1408			for (int y = 0; y < access.getHeight(); y++)
1409				for (int x = 0; x < access.getWidth(); x++)
1410				{
1411					const bool		inner	= x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1412
1413					if (inner && !verify.verifyInner)
1414						continue;
1415					if (!inner && !verify.verifyOuter)
1416						continue;
1417
1418					const tcu::Vec4	ref		= inner ? verify.innerRef : verify.outerRef;
1419					const tcu::Vec4	p		= access.getPixel(x, y);
1420
1421					for (int c = 0; c < 4; c++)
1422						if (fabs(p[c] - ref[c]) > 0.01f)
1423							pass = false;
1424				}
1425
1426		}
1427	}
1428
1429	if (pass)
1430		return tcu::TestStatus::pass("Pass");
1431	else
1432		return tcu::TestStatus::fail("Fail");
1433}
1434
1435} // anonymous
1436
1437tcu::TestCaseGroup* createRenderPassLoadStoreOpNoneTests (tcu::TestContext& testCtx, const SharedGroupParams groupParams)
1438{
1439	de::MovePtr<tcu::TestCaseGroup>		opNoneTests		(new tcu::TestCaseGroup(testCtx, "load_store_op_none"));
1440
1441	const tcu::Vec4	red			(1.0f, 0.0f, 0.0f, 1.0f);
1442	const tcu::Vec4	green		(0.0f, 1.0f, 0.0f, 1.0f);
1443	const tcu::Vec4	magenta		(1.0f, 0.0f, 1.0f, 1.0f);
1444	const tcu::Vec4	darkBlue	(0.0f, 0.0f, 0.5f, 1.0f);
1445	const tcu::Vec4	blend		(0.5f, 0.0f, 0.25f, 0.5f);
1446	const tcu::Vec4	depthInit	(0.5f, 0.0f, 0.0f, 1.0f);
1447	const tcu::Vec4	depthFull	(1.0f, 0.0f, 0.0f, 1.0f);
1448	const tcu::Vec4	stencilInit	(128.0f, 0.0f, 0.0f, 1.0f);
1449	const tcu::Vec4	stencilFull	(255.0f, 0.0f, 0.0f, 1.0f);
1450	const tcu::Vec4	redUint		(255.0f, 0.0f, 0.0f, 255.0f);
1451	const tcu::Vec4	greenUint	(0.0f, 255.0f, 0.0f, 255.0f);
1452
1453	// Preinitialize attachments 0 and 1 to green.
1454	// Subpass 0: draw a red rectangle inside attachment 0.
1455	// Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1456	// attachment 1.
1457	// After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1458	// store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1459	// preinitialized green outside the render area and magenta inside.
1460	if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
1461	{
1462		TestParams params
1463		{
1464			{									// std::vector<AttachmentParams>	attachments;
1465				{
1466					ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1467					VK_ATTACHMENT_LOAD_OP_LOAD,
1468					VK_ATTACHMENT_STORE_OP_NONE_EXT,
1469					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1470					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1471					ATTACHMENT_INIT_PRE,
1472					{{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}
1473				},
1474				{
1475					ATTACHMENT_USAGE_COLOR,
1476					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1477					VK_ATTACHMENT_STORE_OP_STORE,
1478					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1479					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1480					ATTACHMENT_INIT_PRE,
1481					{{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}
1482				}
1483			},
1484			{									// std::vector<SubpassParams>		subpasses;
1485				{{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1486				{{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}
1487			},
1488			groupParams,						// const SharedGroupParams			groupParams;
1489			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1490			false								// bool								alphaBlend;
1491		};
1492
1493		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", params));
1494	}
1495
1496	// Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1497	// disable color writes using an empty color mask. The color attachment image should have the original
1498	// preinitialized value after the render pass.
1499	{
1500		TestParams params
1501		{
1502			{									// std::vector<AttachmentParams>	attachments;
1503				{
1504					ATTACHMENT_USAGE_COLOR,
1505					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1506					VK_ATTACHMENT_STORE_OP_NONE_EXT,
1507					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1508					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1509					ATTACHMENT_INIT_PRE,
1510					{{VK_IMAGE_ASPECT_COLOR_BIT, true, green, true, green}}
1511				}
1512			},
1513			{									// std::vector<SubpassParams>		subpasses;
1514				{{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_COLOR_WRITE_OFF}}, 1u}
1515			},
1516			groupParams,						// const SharedGroupParams			groupParams;
1517			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1518			false								// bool								alphaBlend;
1519		};
1520
1521		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", params));
1522	}
1523
1524	// Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1525	// write a rectangle to the color buffer. The render area is undefined, but the outside area should
1526	// still have the preinitialized color.
1527	{
1528		TestParams params
1529		{
1530			{									// std::vector<AttachmentParams>	attachments;
1531				{
1532					ATTACHMENT_USAGE_COLOR,
1533					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1534					VK_ATTACHMENT_STORE_OP_NONE_EXT,
1535					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1536					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1537					ATTACHMENT_INIT_PRE,
1538					{{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}
1539				}
1540			},
1541			{									// std::vector<SubpassParams>		subpasses;
1542				{{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}
1543			},
1544			groupParams,						// const SharedGroupParams			groupParams;
1545			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1546			false								// bool								alphaBlend;
1547		};
1548
1549		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", params));
1550	}
1551
1552	// Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1553	// do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1554	// data and store op store causes the cleared blue render area to be present after the render pass.
1555	{
1556		TestParams params
1557		{
1558			{									// std::vector<AttachmentParams>	attachments;
1559				{
1560					ATTACHMENT_USAGE_COLOR,
1561					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1562					VK_ATTACHMENT_STORE_OP_STORE,
1563					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1564					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1565					ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1566					{{VK_IMAGE_ASPECT_COLOR_BIT, true, darkBlue, true, green}}
1567				}
1568			},
1569			{									// std::vector<SubpassParams>		subpasses;
1570				{{{0u, ATTACHMENT_USAGE_COLOR}}, 0u}
1571			},
1572			groupParams,						// const SharedGroupParams			groupParams;
1573			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1574			false								// bool								alphaBlend;
1575		};
1576
1577		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", params));
1578	}
1579
1580	// Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1581	// by an alpha blender draw. Load op none preserves the preinitialized data and store op store
1582	// keeps the blended color inside the render area after the render pass.
1583	{
1584		TestParams params
1585		{
1586			{									// std::vector<AttachmentParams>	attachments;
1587				{
1588					ATTACHMENT_USAGE_COLOR,
1589					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1590					VK_ATTACHMENT_STORE_OP_STORE,
1591					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1592					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1593					ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1594					{{VK_IMAGE_ASPECT_COLOR_BIT, true, blend, true, green}}
1595				}
1596			},
1597			{									// std::vector<SubpassParams>		subpasses;
1598				{{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}
1599			},
1600			groupParams,						// const SharedGroupParams			groupParams;
1601			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1602			true								// bool								alphaBlend;
1603		};
1604
1605		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", params));
1606	}
1607
1608	// Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined  because load op 'none'.
1609	// Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1610	// Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1611	// After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1612	// but the outside area should still have the preinitialized content.
1613	// Attachment 1 should have the preinitialized green outside render area and magenta inside.
1614	if (groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
1615	{
1616		TestParams params
1617		{
1618			{									// std::vector<AttachmentParams>	attachments;
1619				{
1620					ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1621					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1622					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1623					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1624					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1625					ATTACHMENT_INIT_PRE,
1626					{{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}
1627				},
1628				{
1629					ATTACHMENT_USAGE_COLOR,
1630					VK_ATTACHMENT_LOAD_OP_LOAD,
1631					VK_ATTACHMENT_STORE_OP_STORE,
1632					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1633					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1634					ATTACHMENT_INIT_PRE,
1635					{{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}
1636				}
1637		},
1638		{									// std::vector<SubpassParams>		subpasses;
1639			{{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1640			{{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}
1641		},
1642		groupParams,						// const SharedGroupParams			groupParams;
1643		VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1644		false								// bool								alphaBlend;
1645		};
1646
1647		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", params));
1648	}
1649
1650	// Preinitialize color attachment to green. Use a render pass with load and store ops none for a multisample color
1651	// target. Write a red rectangle and check it ends up in the resolved buffer even though the multisample attachment
1652	// doesn't store the results.
1653	{
1654		TestParams params
1655		{
1656			{									// std::vector<AttachmentParams>	attachments;
1657				{
1658					ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER,
1659					VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1660					VK_ATTACHMENT_STORE_OP_NONE_EXT,
1661					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1662					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1663					ATTACHMENT_INIT_PRE,
1664					{}
1665				},
1666				{
1667					ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET | ATTACHMENT_USAGE_INTEGER,
1668					VK_ATTACHMENT_LOAD_OP_LOAD,
1669					VK_ATTACHMENT_STORE_OP_STORE,
1670					VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1671					VK_ATTACHMENT_STORE_OP_DONT_CARE,
1672					ATTACHMENT_INIT_PRE,
1673					{{VK_IMAGE_ASPECT_COLOR_BIT, true, redUint, true, greenUint}}
1674				}
1675			},
1676			{									// std::vector<SubpassParams>		subpasses;
1677				{{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER}, {1u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET}}, 1u}
1678			},
1679			groupParams,						// const SharedGroupParams			groupParams;
1680			VK_FORMAT_UNDEFINED,				// VkFormat							depthStencilFormat;
1681			false								// bool								alphaBlend;
1682		};
1683
1684		opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_resolve", params));
1685	}
1686
1687	std::vector<VkFormat>	formats = { VK_FORMAT_D16_UNORM, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_S8_UINT };
1688
1689	for (deUint32 f = 0; f < formats.size(); ++f)
1690	{
1691		const auto			tcuFormat	= mapVkFormat(formats[f]);
1692		const bool			hasDepth	= tcu::hasDepthComponent(tcuFormat.order);
1693		const bool			hasStencil	= tcu::hasStencilComponent(tcuFormat.order);
1694		const std::string	formatName	= getFormatCaseName(formats[f]);
1695
1696		// Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1697		// Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1698		// depth buffer to 1.0.
1699		// This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1700		// the depth test fails and nothing is written.
1701		// After the renderpass the red color should remain inside the render area of the color buffer.
1702		// Store op 'none' for depth buffer makes the written values undefined, but the pixels outside
1703		// render area should still contain the original value of 0.5.
1704		if (hasDepth)
1705		{
1706			TestParams params
1707			{
1708				{									// std::vector<AttachmentParams>	attachments;
1709					{
1710						ATTACHMENT_USAGE_COLOR,
1711						VK_ATTACHMENT_LOAD_OP_LOAD,
1712						VK_ATTACHMENT_STORE_OP_STORE,
1713						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1714						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1715						ATTACHMENT_INIT_PRE,
1716						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1717					},
1718					{
1719						ATTACHMENT_USAGE_DEPTH,
1720						VK_ATTACHMENT_LOAD_OP_LOAD,
1721						VK_ATTACHMENT_STORE_OP_NONE_EXT,
1722						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1723						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1724						ATTACHMENT_INIT_PRE,
1725						{{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthInit, true, depthInit}}
1726					}
1727				},
1728				{									// std::vector<SubpassParams>		subpasses;
1729					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u}
1730				},
1731				groupParams,						// const SharedGroupParams			groupParams;
1732				formats[f],							// VkFormat							depthStencilFormat;
1733				false								// bool								alphaBlend;
1734			};
1735
1736			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_"+formatName+"_load_op_load_store_op_none", params));
1737		}
1738
1739		// Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1740		// disable depth test which also disables depth writes. The depth attachment should have the original
1741		// preinitialized value after the render pass.
1742		if (hasDepth)
1743		{
1744			TestParams params
1745			{
1746				{									// std::vector<AttachmentParams>	attachments;
1747					{
1748						ATTACHMENT_USAGE_COLOR,
1749						VK_ATTACHMENT_LOAD_OP_LOAD,
1750						VK_ATTACHMENT_STORE_OP_STORE,
1751						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1752						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1753						ATTACHMENT_INIT_PRE,
1754						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1755					},
1756					{
1757						ATTACHMENT_USAGE_DEPTH,
1758						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1759						VK_ATTACHMENT_STORE_OP_NONE_EXT,
1760						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1761						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1762						ATTACHMENT_INIT_PRE,
1763						{{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}}
1764					}
1765				},
1766				{									// std::vector<SubpassParams>		subpasses;
1767					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u}
1768				},
1769				groupParams,						// const SharedGroupParams			groupParams;
1770				formats[f],							// VkFormat							depthStencilFormat;
1771				false								// bool								alphaBlend;
1772			};
1773
1774			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_none_write_off", params));
1775		}
1776
1777		// Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1778		// using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1779		// depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1780		// shader updated value of 1.0.
1781		if (hasDepth)
1782		{
1783			TestParams params
1784			{
1785				{									// std::vector<AttachmentParams>	attachments;
1786					{
1787						ATTACHMENT_USAGE_COLOR,
1788						VK_ATTACHMENT_LOAD_OP_LOAD,
1789						VK_ATTACHMENT_STORE_OP_STORE,
1790						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1791						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1792						ATTACHMENT_INIT_PRE,
1793						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1794					},
1795					{
1796						ATTACHMENT_USAGE_DEPTH,
1797						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1798						VK_ATTACHMENT_STORE_OP_STORE,
1799						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1800						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1801						ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1802						{{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}}}
1803				},
1804				{									// std::vector<SubpassParams>		subpasses;
1805					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}
1806				},
1807				groupParams,						// const SharedGroupParams			groupParams;
1808				formats[f],							// VkFormat							depthStencilFormat;
1809				false								// bool								alphaBlend;
1810			};
1811
1812			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_store", params));
1813		}
1814
1815		// Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1816		// using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1817		// After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1818		// area is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1819		if (hasDepth)
1820		{
1821			TestParams params
1822			{
1823				{									// std::vector<AttachmentParams>	attachments;
1824					{
1825						ATTACHMENT_USAGE_COLOR,
1826						VK_ATTACHMENT_LOAD_OP_LOAD,
1827						VK_ATTACHMENT_STORE_OP_STORE,
1828						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1829						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1830						ATTACHMENT_INIT_PRE,
1831						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1832					},
1833					{
1834						ATTACHMENT_USAGE_DEPTH,
1835						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1836						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1837						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1838						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1839						ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1840						{{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthFull, true, depthInit}}
1841					}
1842				},
1843				{									// std::vector<SubpassParams>		subpasses;
1844					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}
1845				},
1846				groupParams,						// const SharedGroupParams			groupParams;
1847				formats[f],							// VkFormat							depthStencilFormat;
1848				false								// bool								alphaBlend;
1849			};
1850
1851			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_dontcare", params));
1852		}
1853
1854		// Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1855		// Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1856		// will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1857		// the stencil test fails and nothing is written.
1858		// After the renderpass the red color should remain inside the render area of the color buffer.
1859		// Store op 'none' for stencil buffer makes the written values undefined, but the pixels outside
1860		// render area should still contain the original value of 128.
1861		if (hasStencil)
1862		{
1863			TestParams params
1864			{
1865				{									// std::vector<AttachmentParams>	attachments;
1866					{
1867						ATTACHMENT_USAGE_COLOR,
1868						VK_ATTACHMENT_LOAD_OP_LOAD,
1869						VK_ATTACHMENT_STORE_OP_STORE,
1870						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1871						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1872						ATTACHMENT_INIT_PRE,
1873						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1874					},
1875					{
1876						ATTACHMENT_USAGE_STENCIL,
1877						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1878						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1879						VK_ATTACHMENT_LOAD_OP_LOAD,
1880						VK_ATTACHMENT_STORE_OP_NONE_EXT,
1881						ATTACHMENT_INIT_PRE,
1882						{{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilInit, true, stencilInit}}
1883					}
1884				},
1885				{									// std::vector<SubpassParams>		subpasses;
1886					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u}
1887				},
1888				groupParams,						// const SharedGroupParams			groupParams;
1889				formats[f],							// VkFormat							depthStencilFormat;
1890				false								// bool								alphaBlend;
1891			};
1892
1893			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_load_store_op_none", params));
1894		}
1895
1896		// Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1897		// disable stencil test which also disables stencil writes. The stencil attachment should have the original
1898		// preinitialized value after the render pass.
1899		if (hasStencil)
1900		{
1901			TestParams params
1902			{
1903				{									// std::vector<AttachmentParams>	attachments;
1904					{
1905						ATTACHMENT_USAGE_COLOR,
1906						VK_ATTACHMENT_LOAD_OP_LOAD,
1907						VK_ATTACHMENT_STORE_OP_STORE,
1908						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1909						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1910						ATTACHMENT_INIT_PRE,
1911						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1912					},
1913					{
1914						ATTACHMENT_USAGE_STENCIL,
1915						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1916						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1917						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1918						VK_ATTACHMENT_STORE_OP_NONE_EXT,
1919						ATTACHMENT_INIT_PRE,
1920						{{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}}
1921					}
1922				},
1923				{									// std::vector<SubpassParams>		subpasses;
1924					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u}
1925				},
1926				groupParams,						// const SharedGroupParams			groupParams;
1927				formats[f],							// VkFormat							depthStencilFormat;
1928				false								// bool								alphaBlend;
1929			};
1930
1931			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_none_write_off", params));
1932		}
1933
1934		// Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1935		// using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1936		// stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1937		// shader updated value of 255.
1938		if (hasStencil)
1939		{
1940			TestParams params
1941			{
1942				{									// std::vector<AttachmentParams>	attachments;
1943					{
1944						ATTACHMENT_USAGE_COLOR,
1945						VK_ATTACHMENT_LOAD_OP_LOAD,
1946						VK_ATTACHMENT_STORE_OP_STORE,
1947						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1948						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1949						ATTACHMENT_INIT_PRE,
1950						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1951					},
1952					{
1953						ATTACHMENT_USAGE_STENCIL,
1954						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1955						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1956						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1957						VK_ATTACHMENT_STORE_OP_STORE,
1958						ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1959						{{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}
1960					}
1961				},
1962				{									// std::vector<SubpassParams>		subpasses;
1963					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}
1964				},
1965				groupParams,						// const SharedGroupParams			groupParams;
1966				formats[f],							// VkFormat							depthStencilFormat;
1967				false								// bool								alphaBlend;
1968			};
1969
1970			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_store", params));
1971		}
1972
1973		// Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1974		// using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
1975		// After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
1976		// are is undefined because of store op 'don't care', but the outside should have the original value of 128.
1977		if (hasStencil)
1978		{
1979			TestParams params
1980			{
1981				{									// std::vector<AttachmentParams>	attachments;
1982					{
1983						ATTACHMENT_USAGE_COLOR,
1984						VK_ATTACHMENT_LOAD_OP_LOAD,
1985						VK_ATTACHMENT_STORE_OP_STORE,
1986						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1987						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1988						ATTACHMENT_INIT_PRE,
1989						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
1990					},
1991					{
1992						ATTACHMENT_USAGE_STENCIL,
1993						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1994						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1995						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1996						VK_ATTACHMENT_STORE_OP_DONT_CARE,
1997						ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1998						{{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilFull, true, stencilInit}}
1999					}
2000				},
2001				{									// std::vector<SubpassParams>		subpasses;
2002					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}
2003				},
2004				groupParams,						// const SharedGroupParams			groupParams;
2005				formats[f],							// VkFormat							depthStencilFormat;
2006				false								// bool								alphaBlend;
2007			};
2008
2009			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_dontcare", params));
2010		}
2011
2012		// Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2013		// rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2014		// color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2015		// store ops none, and stencil writes are disabled by disabling stencil test. Therefore, stencil should not be modified even when
2016		// the depth aspect is written.
2017		if (hasDepth && hasStencil)
2018		{
2019			TestParams params
2020			{
2021				{									// std::vector<AttachmentParams>	attachments;
2022					{
2023						ATTACHMENT_USAGE_COLOR,
2024						VK_ATTACHMENT_LOAD_OP_LOAD,
2025						VK_ATTACHMENT_STORE_OP_STORE,
2026						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2027						VK_ATTACHMENT_STORE_OP_DONT_CARE,
2028						ATTACHMENT_INIT_PRE,
2029						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
2030					},
2031					{
2032						ATTACHMENT_USAGE_DEPTH_STENCIL,
2033						VK_ATTACHMENT_LOAD_OP_LOAD,
2034						VK_ATTACHMENT_STORE_OP_STORE,
2035						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2036						VK_ATTACHMENT_STORE_OP_NONE_EXT,
2037						ATTACHMENT_INIT_PRE,
2038						{
2039							{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2040							{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2041						}
2042					}
2043				},
2044				{									// std::vector<SubpassParams>		subpasses;
2045					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF}}, 1u}
2046				},
2047				groupParams,						// const SharedGroupParams			groupParams;
2048				formats[f],							// VkFormat							depthStencilFormat;
2049				false								// bool								alphaBlend;
2050			};
2051
2052			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_test_off", params));
2053		}
2054
2055		// Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2056		// using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2057		// the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2058		// ops none, and depth writes are disabled by having depth test off. Therefore, depth should not be modified even when the stencil aspect is
2059		// written.
2060		if (hasDepth && hasStencil)
2061		{
2062			TestParams params
2063			{
2064				{									// std::vector<AttachmentParams>	attachments;
2065					{
2066						ATTACHMENT_USAGE_COLOR,
2067						VK_ATTACHMENT_LOAD_OP_LOAD,
2068						VK_ATTACHMENT_STORE_OP_STORE,
2069						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2070						VK_ATTACHMENT_STORE_OP_DONT_CARE,
2071						ATTACHMENT_INIT_PRE,
2072						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
2073					},
2074					{
2075						ATTACHMENT_USAGE_DEPTH_STENCIL,
2076						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2077						VK_ATTACHMENT_STORE_OP_NONE_EXT,
2078						VK_ATTACHMENT_LOAD_OP_LOAD,
2079						VK_ATTACHMENT_STORE_OP_STORE,
2080						ATTACHMENT_INIT_PRE,
2081						{
2082							{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2083							{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}
2084						}
2085					}
2086				},
2087				{									// std::vector<SubpassParams>		subpasses;
2088					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_TEST_OFF}}, 1u}
2089				},
2090				groupParams,						// const SharedGroupParams			groupParams;
2091				formats[f],							// VkFormat							depthStencilFormat;
2092				false								// bool								alphaBlend;
2093			};
2094
2095			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_test_off", params));
2096		}
2097
2098		// Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2099		// rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2100		// color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2101		// store ops none, and stencil writes are disabled. Therefore, stencil should not be modified even when the depth aspect is written.
2102		if (hasDepth && hasStencil)
2103		{
2104			TestParams params
2105			{
2106				{									// std::vector<AttachmentParams>	attachments;
2107					{
2108						ATTACHMENT_USAGE_COLOR,
2109						VK_ATTACHMENT_LOAD_OP_LOAD,
2110						VK_ATTACHMENT_STORE_OP_STORE,
2111						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2112						VK_ATTACHMENT_STORE_OP_DONT_CARE,
2113						ATTACHMENT_INIT_PRE,
2114						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
2115					},
2116					{
2117						ATTACHMENT_USAGE_DEPTH_STENCIL,
2118						VK_ATTACHMENT_LOAD_OP_LOAD,
2119						VK_ATTACHMENT_STORE_OP_STORE,
2120						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2121						VK_ATTACHMENT_STORE_OP_NONE_EXT,
2122						ATTACHMENT_INIT_PRE,
2123						{
2124							{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2125							{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2126						}
2127					}
2128				},
2129				{									// std::vector<SubpassParams>		subpasses;
2130					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_WRITE_OFF}}, 1u}
2131				},
2132				groupParams,						// const SharedGroupParams			groupParams;
2133				formats[f],							// VkFormat							depthStencilFormat;
2134				false								// bool								alphaBlend;
2135			};
2136
2137			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_write_off", params));
2138		}
2139
2140		// Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2141		// using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2142		// the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2143		// ops none, the depth buffer contents will be undefined and depth test is enabled but op will be 'always' so depth testing will pass. Depth
2144		// writes are disabled, so depth should not be modified even when the stencil aspect is written.
2145		if (hasDepth && hasStencil)
2146		{
2147			TestParams params
2148			{
2149				{									// std::vector<AttachmentParams>	attachments;
2150					{
2151						ATTACHMENT_USAGE_COLOR,
2152						VK_ATTACHMENT_LOAD_OP_LOAD,
2153						VK_ATTACHMENT_STORE_OP_STORE,
2154						VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2155						VK_ATTACHMENT_STORE_OP_DONT_CARE,
2156						ATTACHMENT_INIT_PRE,
2157						{{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}
2158					},
2159					{
2160						ATTACHMENT_USAGE_DEPTH_STENCIL,
2161						VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2162						VK_ATTACHMENT_STORE_OP_NONE_EXT,
2163						VK_ATTACHMENT_LOAD_OP_LOAD,
2164						VK_ATTACHMENT_STORE_OP_STORE,
2165						ATTACHMENT_INIT_PRE,
2166						{
2167							{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2168							{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}
2169						}
2170					}
2171				},
2172				{									// std::vector<SubpassParams>		subpasses;
2173					{{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_WRITE_OFF}}, 1u}
2174				},
2175				groupParams,						// const SharedGroupParams			groupParams;
2176				formats[f],							// VkFormat							depthStencilFormat;
2177				false								// bool								alphaBlend;
2178			};
2179
2180			opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depthstencil_" + formatName + "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_write_off", params));
2181		}
2182	}
2183
2184	return opNoneTests.release();
2185}
2186
2187} // renderpass
2188} // vkt
2189