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