• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2020 The Khronos Group Inc.
6  * Copyright (c) 2020 ARM Ltd.
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 VK_ARM_rasterization_order_attachment_access tests.
23  *//*--------------------------------------------------------------------*/
24 
25 #include "deDefs.hpp"
26 #include "deUniquePtr.hpp"
27 #include "tcuCommandLine.hpp"
28 #include "tcuImageCompare.hpp"
29 #include "tcuResource.hpp"
30 #include "tcuTestLog.hpp"
31 #include "tcuStringTemplate.hpp"
32 #include "vkBarrierUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkDefs.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkMemUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "vkPlatform.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkQueryUtil.hpp"
42 #include "vkRef.hpp"
43 #include "vkRefUtil.hpp"
44 #include "vktRasterizationOrderAttachmentAccessTests.hpp"
45 #include "vktRasterizationTests.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vktTestCase.hpp"
48 #include "vktTestCaseUtil.hpp"
49 #include "vktTestGroupUtil.hpp"
50 
51 using namespace vk;
52 using namespace std;
53 using namespace vkt;
54 using de::MovePtr;
55 
56 namespace vkt
57 {
58 
59 namespace rasterization
60 {
61 
62 namespace
63 {
64 
65 class AttachmentAccessOrderTestCase : public TestCase
66 {
67 public:
68 	enum
69 	{
70 		ELEM_NUM = 6
71 	};
72 
73 							AttachmentAccessOrderTestCase(	tcu::TestContext& context, const std::string& name, const std::string& description,
74 															bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
75 															VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat);
76 	virtual					~AttachmentAccessOrderTestCase	(void);
77 
78 	virtual void			initPrograms				(SourceCollections& programCollection) const;
79 	virtual TestInstance*	createInstance				(Context& context) const;
80 	virtual void			checkSupport				(Context& context) const;
81 
82 	virtual deUint32				getInputAttachmentNum() const = 0;
83 	virtual deUint32				getColorAttachmentNum() const = 0;
84 	virtual bool					hasDepthStencil() const = 0;
85 	virtual VkImageAspectFlagBits	getDSAspect() const = 0;
86 
87 
88 
89 
90 	deUint32				m_inputAttachmentNum;
91 	const bool				m_explicitSync;
92 	const bool				m_overlapDraws;
93 	const bool				m_overlapPrimitives;
94 	const bool				m_overlapInstances;
95 	VkSampleCountFlagBits	m_sampleCount;
96 	const deUint32			m_sampleNum;
97 	const bool				m_integerFormat;
98 	static deUint32			getSampleNum(VkSampleCountFlagBits sampleCount);
99 
getColorFormat() const100 	VkFormat getColorFormat() const
101 	{
102 		return m_integerFormat ? VK_FORMAT_R32G32_UINT : VK_FORMAT_R32G32_SFLOAT;
103 	}
104 
105 	VkFormat checkAndGetDSFormat (Context& context) const;
106 
getColorImageType()107 	static VkImageType getColorImageType ()
108 	{
109 		return VK_IMAGE_TYPE_2D;
110 	}
111 
getColorImageTiling()112 	static VkImageTiling getColorImageTiling ()
113 	{
114 		return VK_IMAGE_TILING_OPTIMAL;
115 	}
116 
getColorImageUsageFlags()117 	static VkImageUsageFlags getColorImageUsageFlags ()
118 	{
119 		return
120 			(	VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
121 			|	VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
122 			|	VK_IMAGE_USAGE_TRANSFER_SRC_BIT
123 			|	VK_IMAGE_USAGE_TRANSFER_DST_BIT
124 			);
125 	}
126 
getDSImageUsageFlags()127 	static VkImageUsageFlags getDSImageUsageFlags ()
128 	{
129 		return
130 			(	VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
131 			|	VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
132 			|	VK_IMAGE_USAGE_TRANSFER_SRC_BIT
133 			|	VK_IMAGE_USAGE_TRANSFER_DST_BIT
134 			);
135 	}
136 
getBlendStateFlags() const137 	VkPipelineColorBlendStateCreateFlags getBlendStateFlags() const
138 	{
139 		return m_explicitSync ? 0 : VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM;
140 	}
getDSStateFlags() const141 	virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
142 	{
143 		return 0;
144 	}
hasDepth() const145 	virtual bool hasDepth() const
146 	{
147 		return false;
148 	}
hasStencil() const149 	virtual bool hasStencil() const
150 	{
151 		return false;
152 	}
153 
154 protected:
155 	virtual void			addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const = 0;
156 	void					addSimpleVertexShader(SourceCollections& programCollection, const std::string &dest) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const157 	virtual void			checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
158 	{
159 		// unused parameter
160 		DE_UNREF(rasterizationAccess);
161 	}
162 };
163 
164 class AttachmentAccessOrderColorTestCase : public AttachmentAccessOrderTestCase
165 {
166 public:
AttachmentAccessOrderColorTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,deUint32 inputAttachmentNum,bool integerFormat)167 	AttachmentAccessOrderColorTestCase(	tcu::TestContext& context, const std::string& name, const std::string& description,
168 										bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
169 										VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat)
170 		:AttachmentAccessOrderTestCase(	context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
171 										inputAttachmentNum, integerFormat)
172 	{}
173 
getInputAttachmentNum() const174 	virtual deUint32	getInputAttachmentNum() const
175 	{
176 		return m_inputAttachmentNum;
177 	}
178 
getColorAttachmentNum() const179 	virtual deUint32	getColorAttachmentNum() const
180 	{
181 		return m_inputAttachmentNum;
182 	}
183 
hasDepthStencil() const184 	virtual bool		hasDepthStencil() const
185 	{
186 		return false;
187 	}
188 
getDSAspect() const189 	virtual VkImageAspectFlagBits	getDSAspect() const
190 	{
191 		/* not relevant, this return value will not be used */
192 		return VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
193 	}
194 protected:
195 	virtual void			addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const;
196 };
197 
198 class AttachmentAccessOrderDepthTestCase : public AttachmentAccessOrderTestCase
199 {
200 public:
AttachmentAccessOrderDepthTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)201 	AttachmentAccessOrderDepthTestCase(	tcu::TestContext& context, const std::string& name, const std::string& description,
202 										bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
203 										VkSampleCountFlagBits sampleCount)
204 		:AttachmentAccessOrderTestCase(	context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
205 										1, false)
206 	{}
getInputAttachmentNum() const207 	virtual deUint32	getInputAttachmentNum() const
208 	{
209 		return m_inputAttachmentNum + 1;
210 	}
211 
getColorAttachmentNum() const212 	virtual deUint32	getColorAttachmentNum() const
213 	{
214 		return m_inputAttachmentNum;
215 	}
216 
hasDepth() const217 	virtual bool		hasDepth() const
218 	{
219 		return true;
220 	}
hasDepthStencil() const221 	virtual bool		hasDepthStencil() const
222 	{
223 		return true;
224 	}
225 
getDSAspect() const226 	virtual VkImageAspectFlagBits getDSAspect() const
227 	{
228 		return VK_IMAGE_ASPECT_DEPTH_BIT;
229 	}
getDSStateFlags() const230 	virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
231 	{
232 		return m_explicitSync ? 0 : VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
233 	}
234 protected:
235 	virtual void			addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const236 	virtual void			checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
237 	{
238 		if (!m_explicitSync && !rasterizationAccess.rasterizationOrderDepthAttachmentAccess)
239 		{
240 			TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for depth attachments");
241 		}
242 	}
243 };
244 
245 class AttachmentAccessOrderStencilTestCase : public AttachmentAccessOrderTestCase
246 {
247 public:
AttachmentAccessOrderStencilTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount)248 	AttachmentAccessOrderStencilTestCase(	tcu::TestContext& context, const std::string& name, const std::string& description,
249 											bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
250 											VkSampleCountFlagBits sampleCount)
251 		:AttachmentAccessOrderTestCase(	context, name, description, explicitSync, overlapDraws, overlapPrimitives, overlapInstances, sampleCount,
252 										1, true)
253 	{}
getInputAttachmentNum() const254 	virtual deUint32	getInputAttachmentNum() const
255 	{
256 		return m_inputAttachmentNum + 1;
257 	}
258 
getColorAttachmentNum() const259 	virtual deUint32	getColorAttachmentNum() const
260 	{
261 		return m_inputAttachmentNum;
262 	}
263 
hasStencil() const264 	virtual bool		hasStencil() const
265 	{
266 		return true;
267 	}
hasDepthStencil() const268 	virtual bool		hasDepthStencil() const
269 	{
270 		return true;
271 	}
272 
getDSAspect() const273 	virtual VkImageAspectFlagBits getDSAspect() const
274 	{
275 		return VK_IMAGE_ASPECT_STENCIL_BIT;
276 	}
getDSStateFlags() const277 	virtual VkPipelineDepthStencilStateCreateFlags getDSStateFlags() const
278 	{
279 		return m_explicitSync ? 0 : VK_PIPELINE_DEPTH_STENCIL_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
280 	}
281 protected:
282 	virtual void			addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const;
checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT & rasterizationAccess) const283 	virtual void			checkAdditionalRasterizationFlags(VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT &rasterizationAccess) const
284 	{
285 		if (!m_explicitSync && !rasterizationAccess.rasterizationOrderStencilAttachmentAccess)
286 		{
287 			TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for stencil attachments");
288 		}
289 	}
290 };
291 
292 
293 class AttachmentAccessOrderTestInstance : public TestInstance
294 {
295 public:
296 									AttachmentAccessOrderTestInstance	(Context& context, const AttachmentAccessOrderTestCase *testCase);
297 	virtual							~AttachmentAccessOrderTestInstance	(void);
298 	virtual tcu::TestStatus			iterate								(void);
299 protected:
300 	class RenderSubpass
301 	{
302 	public:
303 		const AttachmentAccessOrderTestCase		*m_testCase;
304 		deUint32								m_subpass;
305 		VkSampleCountFlagBits					m_sampleCount;
306 		Move<VkPipeline>						m_pipeline;
307 		Move<VkPipelineLayout>					m_pipelineLayout;
308 		deUint32								m_colorAttNum;
309 		std::vector<Move<VkImage> >				m_inputAtt;
310 		std::vector<MovePtr<Allocation> >		m_inputAttMemory;
311 		std::vector<Move<VkImageView> >			m_inputAttView;
312 		std::vector<VkAttachmentReference>		m_attachmentReferences;
313 
314 		void createAttachments(	int subpass, deUint32 inputAttachmentNum, deUint32 colorAttachmentNum, VkSampleCountFlagBits sampleCount,
315 								Context &context, vector<VkImageView> &views, VkDescriptorSetLayout *pDsetLayout, const AttachmentAccessOrderTestCase *tc);
316 		void createPipeline(VkRenderPass renderPass, Context &context);
317 
getColorAttachmentNum()318 		deUint32	getColorAttachmentNum()
319 		{
320 			return m_colorAttNum;
321 		}
getInputAttachmentNum()322 		deUint32	getInputAttachmentNum()
323 		{
324 			return static_cast<deUint32>(m_inputAtt.size());
325 		}
getDepthStencilAttachment()326 		VkAttachmentReference*	getDepthStencilAttachment()
327 		{
328 			return (getColorAttachmentNum() == getInputAttachmentNum()) ? DE_NULL : &m_attachmentReferences[m_colorAttNum];
329 		}
330 	};
331 	void							addPipelineBarrier(	VkCommandBuffer			cmdBuffer,
332 														VkImage					image,
333 														VkImageLayout			oldLayout,
334 														VkImageLayout			newLayout,
335 														VkAccessFlags			srcAccessMask,
336 														VkAccessFlags			dstAccessMask,
337 														VkPipelineStageFlags	srcStageMask,
338 														VkPipelineStageFlags	dstStageMask,
339 														VkImageAspectFlags		aspect = VK_IMAGE_ASPECT_COLOR_BIT);
340 
341 	void							addClearColor(VkCommandBuffer cmdBuffer, VkImage image);
342 	void							addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image);
343 
344 	void							writeDescriptorSets();
345 	Move<VkRenderPass>				createRenderPass(VkFormat attFormat);
346 	void							createVertexBuffer();
347 	void							createResultBuffer();
348 	void							addDependency(	vector<VkSubpassDependency> &dependencies, deUint32 source, deUint32 dst,
349 													VkPipelineStageFlags pipelineFlags, VkAccessFlags accessFlags);
350 
351 	tcu::TestStatus					validateResults(deUint32 numDraws, deUint32 numPrimitives, deUint32 numInstances);
352 
353 	const AttachmentAccessOrderTestCase					*m_testCase;
354 
355 
356 	const DeviceInterface&								m_vk;
357 	vector<RenderSubpass>								m_subpasses;
358 	Move<VkRenderPass>									m_renderPass;
359 	Move<VkFramebuffer>									m_framebuffer;
360 	Move<VkBuffer>										m_vertexBuffer;
361 	MovePtr<Allocation>									m_vertexBufferMemory;
362 	Move<VkCommandPool>									m_cmdPool;
363 	Move<VkCommandBuffer>								m_cmdBuffer;
364 	Move<VkSampler>										m_sampler;
365 	Move<VkDescriptorSetLayout>							m_descSetLayout;
366 	Move<VkDescriptorPool>								m_descPool;
367 	Move<VkDescriptorSet>								m_descSet;
368 
369 	Move<VkBuffer>										m_resultBuffer;
370 	MovePtr<Allocation>									m_resultBufferMemory;
371 
372 	enum
373 	{
374 		WIDTH = 8,
375 		HEIGHT = 8,
376 	};
377 };
378 
AttachmentAccessOrderTestCase(tcu::TestContext & context,const std::string & name,const std::string & description,bool explicitSync,bool overlapDraws,bool overlapPrimitives,bool overlapInstances,VkSampleCountFlagBits sampleCount,deUint32 inputAttachmentNum,bool integerFormat)379 AttachmentAccessOrderTestCase::AttachmentAccessOrderTestCase (	tcu::TestContext& context, const std::string& name, const std::string& description,
380 																bool explicitSync, bool overlapDraws, bool overlapPrimitives, bool overlapInstances,
381 																VkSampleCountFlagBits sampleCount, deUint32 inputAttachmentNum, bool integerFormat)
382 	: TestCase(context, name, description)
383 	, m_inputAttachmentNum(inputAttachmentNum)
384 	, m_explicitSync(explicitSync)
385 	, m_overlapDraws(overlapDraws)
386 	, m_overlapPrimitives(overlapPrimitives)
387 	, m_overlapInstances(overlapInstances)
388 	, m_sampleCount(sampleCount)
389 	, m_sampleNum(getSampleNum(sampleCount))
390 	, m_integerFormat(integerFormat)
391 {
392 }
393 
~AttachmentAccessOrderTestCase(void)394 AttachmentAccessOrderTestCase::~AttachmentAccessOrderTestCase (void)
395 {
396 }
addSimpleVertexShader(SourceCollections & programCollection,const std::string & dest) const397 void AttachmentAccessOrderTestCase::addSimpleVertexShader(SourceCollections& programCollection, const std::string &dest) const
398 {
399 	/*
400 	 * The "prim_id" variable here (and in other tests below) is emulating gl_PrimitiveID.
401 	 * This is done to avoid having this test dependon the geometry shader feature.
402 	 * Note that this emulation only works because the draw calls used in the tests are
403 	 * non-indexed independent triangles.
404 	 */
405 	std::stringstream vertShader;
406 	vertShader	<< "#version 310 es\n"
407 				<< "layout(location = 0) in highp vec2 v_position;\n"
408 	                        << "layout(location = 1) flat out int prim_id;\n"
409 				<< "void main ()\n"
410 				<< "{\n"
411 	                        << "    prim_id = gl_VertexIndex / 3;\n"
412 				<< "	gl_Position = vec4(v_position, float(gl_InstanceIndex)/256.0, 1);\n"
413 				<< "}\n";
414 
415 	programCollection.glslSources.add(dest) << glu::VertexSource(vertShader.str());
416 }
417 
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const418 void AttachmentAccessOrderColorTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const
419 {
420 	addSimpleVertexShader(programCollection, "vert1");
421 	addSimpleVertexShader(programCollection, "vert2");
422 
423 	std::stringstream fragShader;
424 	fragShader	<< "#version 450\n"
425 				<< "precision highp ${SCALAR_NAME};\n"
426 				<< "precision highp ${SUBPASS_INPUT};\n";
427 	for (deUint32 i=0; i < m_inputAttachmentNum; i++)
428 	{
429 		fragShader	<< "layout( set = 0, binding = " << i << ", input_attachment_index = " << i << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n"
430 					<< "layout( location = " << i << " ) out ${VEC_NAME}2 out" << i << ";\n";
431 	}
432 
433 	fragShader	<< "layout( push_constant ) uniform ConstBlock\n"
434 				<< "{\n"
435 				<< "	uint drawCur;\n"
436 				<< "};\n"
437 				<< "layout(location = 1) flat in int prim_id;\n"
438 				<< "void main()\n"
439 				<< "{\n"
440 				<< "	uint instanceCur = uint(round(gl_FragCoord.z * 256.0));\n"
441 				<< "	uint primitiveCur = uint(prim_id) / 2u;\n"
442 				<< "	uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
443 				<< "	uint instanceNum = ${INSTANCE_NUM}u;\n"
444 				<< "	uint drawNum = ${DRAW_NUM}u;\n"
445 				<< "	uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
446 				<< "	uint total = drawNum * instanceNum * primitiveNum;\n"
447 				<< "	uint zero = curIndex / total;\n"
448 				<< "	uint index;\n"
449 				<< "	uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
450 				<< "	uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
451 				<< "	for(index = 0u; index < pre_fetch_loop; index++)\n"
452 				<< "	{\n"
453 				<< "		zero = uint(sin(float(zero)));\n"
454 				<< "	}\n"
455 				<< "	${VEC_NAME}2 previous[${ATT_NUM}];\n";
456 
457 	for (deUint32 i=0; i < m_inputAttachmentNum; i++)
458 	{
459 		if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
460 		{
461 			fragShader	<< "	previous[" << i << "] = subpassLoad( in" << i << ").xy;\n";
462 		}
463 		else
464 		{
465 			fragShader	<< "	previous[" << i << "] = subpassLoad( in" << i << ", gl_SampleID).xy;\n";
466 		}
467 	}
468 	fragShader	<< "	for(index = 0u; index < post_fetch_loop; index++)\n"
469 				<< "	{\n"
470 				<< "		zero = uint(sin(float(zero)));\n"
471 				<< "	}\n";
472 	for (deUint32 i=0; i < m_inputAttachmentNum; i++)
473 	{
474 		fragShader	<< "	if (previous[" << i << "].y == 0 && curIndex == 0)\n"
475 					<< "	{\n"
476 					<< "		out" << i << ".y = previous[" << i << "].y + (1u + zero + gl_SampleID + " << i << "u);\n"
477 					<< "		out" << i << ".x = previous[" << i << "].x;\n"
478 					<< "	}\n"
479 					<< "	else if (previous[" << i << "].y == curIndex + gl_SampleID + " << i << ")\n"
480 					<< "	{\n"
481 					<< "		out" << i << ".y = previous[" << i << "].y + 1 + zero;\n"
482 					<< "		out" << i << ".x = previous[" << i << "].x;\n"
483 					<< "	}\n"
484 					<< "	else\n"
485 					<< "	{\n"
486 					<< "		out" << i << ".y = 0u;\n"
487 					<< "		out" << i << ".x = 1u;\n"
488 					<< "	}\n";
489 	}
490 	fragShader	<< "}\n";
491 
492 	tcu::StringTemplate fragShaderTpl(fragShader.str());
493 
494 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
495 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const496 void AttachmentAccessOrderDepthTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const
497 {
498 	std::stringstream vertShader;
499 	vertShader	<< "#version 460\n"
500 				<< "layout(location = 0) in highp vec2 v_position;\n"
501 				<< "layout(location = 1) flat out uint instance_index;\n"
502 	                        << "layout(location = 2) flat out int prim_id;\n"
503 				<< "layout( push_constant ) uniform ConstBlock\n"
504 				<< "{\n"
505 				<< "	uint drawCur;\n"
506 				<< "};\n"
507 				<< "void main ()\n"
508 				<< "{\n"
509 				<< "	uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
510 	                        << "    prim_id = gl_VertexIndex / 3;\n"
511 				<< "	uint instanceNum = ${INSTANCE_NUM};\n"
512 				<< "	uint primitiveNum = ${PRIMITIVE_NUM};\n"
513 				<< "	uint drawNum = ${DRAW_NUM};\n"
514 				<< "	uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + primitiveCur;\n"
515 				<< "	uint indexNum = drawNum * instanceNum * primitiveNum;\n"
516 				<< "	instance_index = gl_InstanceIndex;\n"
517 				<< "	gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
518 				<< "}\n";
519 
520 	tcu::StringTemplate vertShaderTpl(vertShader.str());
521 	programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
522 	addSimpleVertexShader(programCollection, "vert2");
523 
524 	std::stringstream fragShader;
525 	fragShader	<< "#version 450\n"
526 				<< "precision highp ${SCALAR_NAME};\n"
527 				<< "precision highp ${SUBPASS_INPUT};\n"
528 				<< "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
529 				<< "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
530 				<< "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
531 				<< "layout( location = 1 ) flat in uint instance_index;\n"
532 	                        << "layout( location = 2 ) flat in int prim_id;\n"
533 				<< "layout( push_constant ) uniform ConstBlock\n"
534 				<< "{\n"
535 				<< "	uint drawCur;\n"
536 				<< "};\n"
537 				<< "void main()\n"
538 				<< "{\n"
539 				<< "	uint instanceCur = instance_index;\n"
540 				<< "	uint primitiveCur = uint(prim_id) / 2u;\n"
541 				<< "	uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
542 				<< "	uint instanceNum = ${INSTANCE_NUM}u;\n"
543 				<< "	uint drawNum = ${DRAW_NUM}u;\n"
544 				<< "	uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
545 				<< "	uint total = drawNum * instanceNum * primitiveNum;\n"
546 				<< "	uint zero = curIndex / total;\n"
547 				<< "	uint index;\n"
548 				<< "	uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
549 				<< "	uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
550 				<< "	for(index = 0u; index < pre_fetch_loop; index++)\n"
551 				<< "	{\n"
552 				<< "		zero = uint(sin(float(zero)));\n"
553 				<< "	}\n";
554 	if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
555 	{
556 		fragShader	<< "	vec2 ds = subpassLoad( in_ds ).xy;\n"
557 					<< "	${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
558 	}
559 	else
560 	{
561 		fragShader	<< "	vec2 ds = subpassLoad( in_ds, gl_SampleID ).xy;\n"
562 					<< "	${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID ).xy;\n";
563 	}
564 	fragShader	<< "	for(index = 0u; index < post_fetch_loop; index++)\n"
565 				<< "	{\n"
566 				<< "		zero = uint(sin(float(zero)));\n"
567 				<< "	}\n"
568 				<< "	if (curIndex == 0 && ds.x == 0)\n"
569 				<< "	{\n"
570 				<< "		out0.x = color.x;\n"
571 				<< "		out0.y = curIndex + 1 + gl_SampleID + zero;\n";
572 	if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
573 	{
574 		fragShader	<< "		gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
575 	}
576 	fragShader	<< "	}\n"
577 				<< "	else\n"
578 				<< "	{\n"
579 				<< "		const float expected = 0.125 * float(curIndex - 1) / float(total) + gl_SampleID / 128.0;\n"
580 				<< "		const float threshold = 0.0000001;\n"
581 				<< "		if (ds.x >= expected - threshold && ds.x <= expected + threshold)\n"
582 				<< "		{\n"
583 				<< "			out0.x = color.x;\n"
584 				<< "			out0.y = curIndex + 1 + gl_SampleID + zero;\n";
585 	if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
586 	{
587 		fragShader	<< "			gl_FragDepth = 0.125 * (float(curIndex) / float(total)) + gl_SampleID / 128.0;\n";
588 	}
589 	fragShader	<< "		}\n"
590 				<< "		else\n"
591 				<< "		{\n"
592 				<< "			out0.y = 0;\n"
593 				<< "			out0.x = 1u;\n"
594 				<< "		}\n"
595 				<< "	}\n"
596 				<< "}\n";
597 
598 	tcu::StringTemplate fragShaderTpl(fragShader.str());
599 
600 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
601 }
addShadersInternal(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const602 void AttachmentAccessOrderStencilTestCase::addShadersInternal(SourceCollections& programCollection, const std::map<std::string, std::string> &params) const
603 {
604 	std::stringstream vertShader;
605 	vertShader	<< "#version 460\n"
606 				<< "layout(location = 0) in highp vec2 v_position;\n"
607 				<< "layout(location = 1) flat out uint instance_index;"
608 	                        << "layout(location = 2) flat out int prim_id;\n"
609 				<< "layout( push_constant ) uniform ConstBlock\n"
610 				<< "{\n"
611 				<< "	uint drawCur;\n"
612 				<< "};\n"
613 				<< "void main ()\n"
614 				<< "{\n"
615 				<< "	uint primitiveCur = uint(gl_VertexIndex) / 6u;\n"
616 	                        << "    prim_id = gl_VertexIndex / 3;\n"
617 				<< "	uint instanceNum = ${INSTANCE_NUM};\n"
618 				<< "	uint primitiveNum = ${PRIMITIVE_NUM};\n"
619 				<< "	uint drawNum = ${DRAW_NUM};\n"
620 				<< "	uint curIndex = drawCur * instanceNum * primitiveNum + gl_InstanceIndex * primitiveNum + primitiveCur;\n"
621 				<< "	uint indexNum = drawNum * instanceNum * primitiveNum;\n"
622 				<< "	instance_index = gl_InstanceIndex;\n"
623 				<< "	gl_Position = vec4(v_position, 0.125 * float(curIndex) / float(indexNum), 1);\n"
624 				<< "}\n";
625 
626 	tcu::StringTemplate vertShaderTpl(vertShader.str());
627 	programCollection.glslSources.add("vert1") << glu::VertexSource(vertShaderTpl.specialize(params));
628 	addSimpleVertexShader(programCollection, "vert2");
629 
630 	std::stringstream fragShader;
631 	fragShader	<< "#version 450\n"
632 				<< "precision highp ${SCALAR_NAME};\n"
633 				<< "precision highp ${SUBPASS_INPUT};\n"
634 				<< "layout( set = 0, binding = 0, input_attachment_index = 0 ) uniform ${SUBPASS_INPUT} in_color;\n"
635 				<< "layout( set = 0, binding = 1, input_attachment_index = 1 ) uniform ${SUBPASS_INPUT} in_ds;\n"
636 				<< "layout( location = 0 ) out ${VEC_NAME}2 out0;\n"
637 				<< "layout( location = 1 ) flat in uint instance_index;\n"
638 	                        << "layout( location = 2 ) flat in int prim_id;\n"
639 				<< "layout( push_constant ) uniform ConstBlock\n"
640 				<< "{\n"
641 				<< "	uint drawCur;\n"
642 				<< "};\n"
643 				<< "void main()\n"
644 				<< "{\n"
645 				<< "	uint instanceCur = instance_index;\n"
646 				<< "	uint primitiveCur = uint(prim_id) / 2u;\n"
647 				<< "	uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
648 				<< "	uint instanceNum = ${INSTANCE_NUM}u;\n"
649 				<< "	uint drawNum = ${DRAW_NUM}u;\n"
650 				<< "	uint curIndex = drawCur * instanceNum * primitiveNum + instanceCur * primitiveNum + primitiveCur;\n"
651 				<< "	uint total = drawNum * instanceNum * primitiveNum;\n"
652 				<< "	uint zero = curIndex / total;\n"
653 				<< "	uint index;\n"
654 				<< "	uint pre_fetch_loop = uint(gl_FragCoord.x) * uint(gl_FragCoord.y) * (drawNum * primitiveNum - drawCur * primitiveNum - primitiveCur);\n"
655 				<< "	uint post_fetch_loop = uint(gl_FragCoord.x) + uint(gl_FragCoord.y) + (drawNum * instanceNum - drawCur * instanceNum - instanceCur);\n"
656 				<< "	for(index = 0u; index < pre_fetch_loop; index++)\n"
657 				<< "	{\n"
658 				<< "		zero = uint(sin(float(zero)));\n"
659 				<< "	}\n";
660 	if (m_sampleCount == VK_SAMPLE_COUNT_1_BIT)
661 	{
662 		fragShader	<< "	${VEC_NAME}2 ds = subpassLoad( in_ds ).xy;\n"
663 					<< "	${VEC_NAME}2 color = subpassLoad( in_color ).xy;\n";
664 	}
665 	else
666 	{
667 		fragShader	<< "	${VEC_NAME}2 ds = subpassLoad( in_ds, gl_SampleID).xy;\n"
668 					<< "	${VEC_NAME}2 color = subpassLoad( in_color, gl_SampleID).xy;\n";
669 	}
670 	fragShader	<< "	for(index = 0u; index < post_fetch_loop; index++)\n"
671 				<< "	{\n"
672 				<< "		zero = uint(sin(float(zero)));\n"
673 				<< "	}\n"
674 				<< "	if (ds.x == curIndex)\n"
675 				<< "	{\n"
676 				<< "		out0.x = color.x;\n"
677 				<< "		out0.y = curIndex + 1 + gl_SampleID + zero;\n"
678 				<< "	}\n"
679 				<< "	else\n"
680 				<< "	{\n"
681 				<< "		out0.y = 0;\n"
682 				<< "		out0.x = 1u;\n"
683 				<< "	}\n"
684 				<< "}\n";
685 
686 	tcu::StringTemplate fragShaderTpl(fragShader.str());
687 
688 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
689 }
690 
initPrograms(SourceCollections & programCollection) const691 void AttachmentAccessOrderTestCase::initPrograms (SourceCollections& programCollection) const
692 {
693 	std::map<std::string, std::string> params;
694 
695 	params["PRIMITIVE_NUM"] = std::to_string(m_overlapPrimitives?ELEM_NUM:1);
696 	params["INSTANCE_NUM"] = std::to_string(m_overlapInstances?ELEM_NUM:1);
697 	params["DRAW_NUM"] = std::to_string(m_overlapDraws?ELEM_NUM:1);
698 	params["ATT_NUM"] = std::to_string(m_inputAttachmentNum);
699 	params["SAMPLE_NUM"] = std::to_string(m_sampleNum);
700 
701 	if (m_integerFormat)
702 	{
703 		params["SUBPASS_INPUT"] = "usubpassInput";
704 		params["SCALAR_NAME"] = "int";
705 		params["VEC_NAME"] = "uvec";
706 	}
707 	else
708 	{
709 		params["SUBPASS_INPUT"] = "subpassInput";
710 		params["SCALAR_NAME"] = "float";
711 		params["VEC_NAME"] = "vec";
712 	}
713 	if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT)
714 	{
715 		params["SUBPASS_INPUT"] = params["SUBPASS_INPUT"] + "MS";
716 	}
717 
718 	/* add the vertex (for both renderpasses) and fragment shaders for first renderpass */
719 	addShadersInternal(programCollection, params);
720 
721 	std::stringstream fragShaderResolve;
722 	fragShaderResolve	<< "#version 450\n"
723 						<< "precision highp ${SCALAR_NAME};\n"
724 						<< "precision highp ${SUBPASS_INPUT};\n";
725 	for (deUint32 i=0; i < m_inputAttachmentNum; i++)
726 	{
727 		fragShaderResolve	<< "layout( set = 0, binding = " << i << ", input_attachment_index = " << i << " ) uniform ${SUBPASS_INPUT} in" << i << ";\n";
728 	}
729 	fragShaderResolve << "layout( location = 0 ) out ${VEC_NAME}2 out0;\n";
730 
731 	fragShaderResolve	<< "void main()\n"
732 						<< "{\n"
733 						<< "	uint primitiveNum = ${PRIMITIVE_NUM}u;\n"
734 						<< "	uint instanceNum = ${INSTANCE_NUM}u;\n"
735 						<< "	uint drawNum = ${DRAW_NUM}u;\n"
736 						<< "	uint sampleNum = ${SAMPLE_NUM}u;\n"
737 						<< "	uint totalNum = primitiveNum * instanceNum * drawNum;\n"
738 						<< "	out0.y = totalNum;\n"
739 						<< "	out0.x = 0u;\n"
740 						<< "	${VEC_NAME}2 val;\n"
741 						<< "	int i;\n";
742 
743 	for (deUint32 i=0; i < m_inputAttachmentNum; i++)
744 	{
745 		if (m_sampleNum == 1)
746 		{
747 			fragShaderResolve	<< "	val = subpassLoad(in" << i << ").xy;\n"
748 								<< "	if (val.x != 0u || val.y != totalNum + " << i << "){\n"
749 								<< "		out0.y = val.y;\n"
750 								<< "		out0.x = val.x;\n"
751 								<< "	}\n";
752 		}
753 		else
754 		{
755 			fragShaderResolve	<< "	for (i = 0; i < sampleNum; i++) {\n"
756 								<< "		val = subpassLoad(in" << i << ", i).xy;\n"
757 								<< "		if (val.x != 0u || val.y != totalNum + i + " << i << "){\n"
758 								<< "			out0.y = val.y;\n"
759 								<< "			out0.x = val.x;\n"
760 								<< "		}\n"
761 								<< "	}\n";
762 		}
763 	}
764 
765 	fragShaderResolve << "}\n";
766 
767 	tcu::StringTemplate fragShaderResolveTpl(fragShaderResolve.str());
768 
769 	programCollection.glslSources.add("frag_resolve") << glu::FragmentSource(fragShaderResolveTpl.specialize(params));
770 }
771 
772 
createInstance(Context & context) const773 TestInstance* AttachmentAccessOrderTestCase::createInstance (Context& context) const
774 {
775 	return new AttachmentAccessOrderTestInstance(context, this);
776 }
777 
checkAndGetDSFormat(Context & context) const778 VkFormat AttachmentAccessOrderTestCase::checkAndGetDSFormat (Context& context) const
779 {
780 	const auto&	vki				= context.getInstanceInterface();
781 	const auto	physicalDevice	= context.getPhysicalDevice();
782 	const auto	imageType		= getColorImageType();
783 	const auto	imageTiling		= getColorImageTiling();
784 	const auto	imageUsage		= getDSImageUsageFlags();
785 
786 	const std::vector<VkFormat>	dsFormats		{ VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT };
787 	VkFormat					supportedFormat	= VK_FORMAT_UNDEFINED;
788 	VkImageFormatProperties		formatProperties;
789 
790 	for (const auto& dsFormat : dsFormats)
791 	{
792 		const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, dsFormat, imageType, imageTiling, imageUsage, 0u, &formatProperties);
793 
794 		if (result == VK_SUCCESS)
795 		{
796 			if ((formatProperties.sampleCounts & m_sampleCount) != 0)
797 			{
798 				supportedFormat = dsFormat;
799 				break;
800 			}
801 		}
802 		else if (result != VK_ERROR_FORMAT_NOT_SUPPORTED)
803 			TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
804 	}
805 
806 	return supportedFormat;
807 }
808 
checkSupport(Context & context) const809 void AttachmentAccessOrderTestCase::checkSupport (Context& context) const
810 {
811 	context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
812 
813 	// When explicit synchronization is used, there's no need for the extension.
814 	if (!m_explicitSync)
815 		if (!context.isDeviceFunctionalitySupported("VK_ARM_rasterization_order_attachment_access") && !context.isDeviceFunctionalitySupported("VK_EXT_rasterization_order_attachment_access"))
816 			TCU_THROW(NotSupportedError, "Neither VK_ARM_rasterization_order_attachment_access nor VK_EXT_rasterization_order_attachment_access is supported");
817 
818 	const auto&	vki				= context.getInstanceInterface();
819 	const auto	physicalDevice	= context.getPhysicalDevice();
820 
821 	VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT	rasterizationAccess	= initVulkanStructure();
822 	VkPhysicalDeviceFeatures2										features2			= initVulkanStructure(m_explicitSync ? nullptr : &rasterizationAccess);
823 
824 	vki.getPhysicalDeviceFeatures2(physicalDevice, &features2);
825 
826 	VkPhysicalDeviceProperties2 properties2 = initVulkanStructure();
827 
828 	vki.getPhysicalDeviceProperties2(physicalDevice, &properties2);
829 
830 	if (m_integerFormat)
831 	{
832 		const auto format		= getColorFormat();
833 		const auto imageType	= getColorImageType();
834 		const auto imageTiling	= getColorImageTiling();
835 		const auto imageUsage	= getColorImageUsageFlags();
836 
837 		VkImageFormatProperties formatProperties;
838 
839 		const auto result = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, imageType, imageTiling, imageUsage, 0u, &formatProperties);
840 		if (result != VK_SUCCESS)
841 		{
842 			if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
843 				TCU_THROW(NotSupportedError, "Error: format " + de::toString(format) + " does not support the required features");
844 			else
845 				TCU_FAIL("vkGetPhysicalDeviceImageFormatProperties returned unexpected error");
846 		}
847 
848 		if ((formatProperties.sampleCounts & m_sampleCount) == 0 ||
849 			(properties2.properties.limits.sampledImageIntegerSampleCounts & m_sampleCount) == 0)
850 		{
851 			TCU_THROW(NotSupportedError, "Sample count not supported");
852 		}
853 	}
854 	else
855 	{
856 		if ((properties2.properties.limits.framebufferColorSampleCounts & m_sampleCount) == 0 ||
857 			(properties2.properties.limits.sampledImageColorSampleCounts & m_sampleCount) == 0)
858 		{
859 			TCU_THROW(NotSupportedError , "Sample count not supported");
860 		}
861 	}
862 
863 	// Check depth/stencil format support if needed.
864 	if (getInputAttachmentNum() > getColorAttachmentNum())
865 	{
866 		const auto format = checkAndGetDSFormat(context);
867 		if (format == VK_FORMAT_UNDEFINED)
868 			TCU_THROW(NotSupportedError, "No support for any of the required depth/stencil formats");
869 	}
870 
871 	/* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */
872 	if (m_sampleCount != VK_SAMPLE_COUNT_1_BIT && !features2.features.sampleRateShading)
873 	{
874 		TCU_THROW(NotSupportedError , "sampleRateShading feature not supported");
875 	}
876 
877 	if (properties2.properties.limits.maxFragmentOutputAttachments < m_inputAttachmentNum ||
878 		properties2.properties.limits.maxPerStageDescriptorInputAttachments < m_inputAttachmentNum)
879 	{
880 		TCU_THROW(NotSupportedError , "Feedback attachment number not supported");
881 	}
882 
883 	if (!m_explicitSync && !rasterizationAccess.rasterizationOrderColorAttachmentAccess)
884 	{
885 		TCU_THROW(NotSupportedError , "Implicit attachment access rasterization order not guaranteed for color attachments");
886 	}
887 
888 	checkAdditionalRasterizationFlags(rasterizationAccess);
889 }
890 
getSampleNum(VkSampleCountFlagBits sampleCount)891 deUint32 AttachmentAccessOrderTestCase::getSampleNum(VkSampleCountFlagBits sampleCount)
892 {
893 	deUint32 ret = 0;
894 	switch(sampleCount)
895 	{
896 		case VK_SAMPLE_COUNT_1_BIT: ret = 1; break;
897 		case VK_SAMPLE_COUNT_2_BIT: ret = 2; break;
898 		case VK_SAMPLE_COUNT_4_BIT: ret = 4; break;
899 		case VK_SAMPLE_COUNT_8_BIT: ret = 8; break;
900 		case VK_SAMPLE_COUNT_16_BIT: ret = 16; break;
901 		case VK_SAMPLE_COUNT_32_BIT: ret = 32; break;
902 		case VK_SAMPLE_COUNT_64_BIT: ret = 64; break;
903 		default: DE_ASSERT(false);
904 	};
905 	return ret;
906 }
907 
createAttachments(int subpass,deUint32 inputAttachmentNum,deUint32 colorAttachmentNum,VkSampleCountFlagBits sampleCount,Context & context,vector<VkImageView> & views,VkDescriptorSetLayout * pDsetLayout,const AttachmentAccessOrderTestCase * tc)908 void AttachmentAccessOrderTestInstance::RenderSubpass::createAttachments(	int subpass, deUint32 inputAttachmentNum, deUint32 colorAttachmentNum,
909 																			VkSampleCountFlagBits sampleCount,
910 																			Context &context, vector<VkImageView> &views, VkDescriptorSetLayout *pDsetLayout,
911 																			const AttachmentAccessOrderTestCase *tc)
912 {
913 	m_testCase = tc;
914 	m_subpass = subpass;
915 	m_sampleCount = sampleCount;
916 	m_colorAttNum = colorAttachmentNum;
917 	const DeviceInterface& vk = context.getDeviceInterface();
918 	const VkDevice device = context.getDevice();
919 	const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
920 	Allocator& allocator = context.getDefaultAllocator();
921 
922 	// Pipeline Layout
923 	{
924 		VkPushConstantRange pushConstantsInfo =
925 		{
926 			VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
927 			0,								// uint32_t				offset;
928 			4,								// uint32_t				size;
929 		};
930 		if (m_testCase->hasDepthStencil())
931 		{
932 			pushConstantsInfo.stageFlags |= VK_SHADER_STAGE_VERTEX_BIT;
933 		}
934 		const VkPipelineLayoutCreateInfo		pipelineLayoutCreateInfo	=
935 		{
936 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType				sType;
937 			DE_NULL,												// const void*					pNext;
938 			0u,														// VkPipelineLayoutCreateFlags	flags;
939 			1u,														// deUint32						descriptorSetCount;
940 			pDsetLayout,											// const VkDescriptorSetLayout*	pSetLayouts;
941 			m_subpass == 0 ? 1u : 0u,								// deUint32						pushConstantRangeCount;
942 			m_subpass == 0 ? &pushConstantsInfo : nullptr			// const VkPushConstantRange*	pPushConstantRanges;
943 		};
944 		m_pipelineLayout					= createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
945 	}
946 	VkFormat attFormat = m_testCase->getColorFormat();
947 
948 	/* Same create info for all the color attachments */
949 	const auto imageType	= AttachmentAccessOrderTestCase::getColorImageType();
950 	const auto imageTiling	= AttachmentAccessOrderTestCase::getColorImageTiling();
951 	const auto imageUsage	= AttachmentAccessOrderTestCase::getColorImageUsageFlags();
952 
953 	VkImageCreateInfo colorImageCreateInfo =
954 	{
955 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,			// VkStructureType			sType;
956 		DE_NULL,										// const void*				pNext;
957 		0u,												// VkImageCreateFlags		flags;
958 		imageType,										// VkImageType				imageType;
959 		attFormat,										// VkFormat					format;
960 		{ WIDTH,	HEIGHT, 1u },						// VkExtent3D				extent;
961 		1u,												// deUint32					mipLevels;
962 		1u,												// deUint32					arrayLayers;
963 		sampleCount,									// VkSampleCountFlagBits	samples;
964 		imageTiling,									// VkImageTiling			tiling;
965 		imageUsage,										// VkImageUsageFlags		usage;
966 		VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode;
967 		1u,												// deUint32					queueFamilyIndexCount;
968 		&queueFamilyIndex,								// const deUint32*			pQueueFamilyIndices;
969 		VK_IMAGE_LAYOUT_UNDEFINED							// VkImageLayout			initialLayout;
970 	};
971 
972 	for (deUint32 i = 0; i < inputAttachmentNum; i++)
973 	{
974 		VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT;
975 
976 		/* Image for the DS attachment */
977 		if (i >= colorAttachmentNum)
978 		{
979 			attFormat = m_testCase->checkAndGetDSFormat(context);
980 			DE_ASSERT(attFormat != VK_FORMAT_UNDEFINED);
981 			colorImageCreateInfo.format = attFormat;
982 			colorImageCreateInfo.usage = AttachmentAccessOrderTestCase::getDSImageUsageFlags();
983 			aspect = m_testCase->getDSAspect();
984 		}
985 
986 		m_inputAtt.push_back(createImage(vk, device, &colorImageCreateInfo, DE_NULL));
987 		VkImageViewCreateInfo colorTargetViewInfo =
988 		{
989 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,	// VkStructureType			sType;
990 			DE_NULL,									// const void*				pNext;
991 			0u,											// VkImageViewCreateFlags	flags;
992 			*m_inputAtt.back(),							// VkImage					image;
993 			VK_IMAGE_VIEW_TYPE_2D,						// VkImageViewType			viewType;
994 			attFormat,									// VkFormat					format;
995 			makeComponentMappingRGBA(),					// VkComponentMapping		components;
996 			{
997 				aspect,										// VkImageAspectFlags			aspectMask;
998 				0u,											// deUint32						baseMipLevel;
999 				1u,											// deUint32						mipLevels;
1000 				0u,											// deUint32						baseArrayLayer;
1001 				1u,											// deUint32						arraySize;
1002 			},											// VkImageSubresourceRange		subresourceRange;
1003 		};
1004 		m_inputAttMemory.push_back(allocator.allocate(getImageMemoryRequirements(vk, device, *m_inputAtt.back()), MemoryRequirement::Any));
1005 		VK_CHECK(vk.bindImageMemory(device, *m_inputAtt.back(), m_inputAttMemory.back()->getMemory(), m_inputAttMemory.back()->getOffset()));
1006 		m_inputAttView.push_back(createImageView(vk, device, &colorTargetViewInfo));
1007 
1008 		m_attachmentReferences.push_back({(deUint32)views.size(), VK_IMAGE_LAYOUT_GENERAL});
1009 		views.push_back(*m_inputAttView.back());
1010 	}
1011 }
1012 
createPipeline(VkRenderPass renderPass,Context & context)1013 void AttachmentAccessOrderTestInstance::RenderSubpass::createPipeline(VkRenderPass renderPass, Context &context)
1014 {
1015 
1016 	const DeviceInterface& vk = context.getDeviceInterface();
1017 	const VkDevice device = context.getDevice();
1018 	const Unique<VkShaderModule> vs(createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "vert1" : "vert2"), 0));
1019 	const Unique<VkShaderModule> fs(createShaderModule(vk, device, context.getBinaryCollection().get(m_subpass == 0 ? "frag" : "frag_resolve"), 0));
1020 
1021 	const VkVertexInputBindingDescription vertexInputBindingDescription =
1022 	{
1023 		0,								// deUint32					binding;
1024 		sizeof(tcu::Vec2),				// deUint32					strideInBytes;
1025 		VK_VERTEX_INPUT_RATE_VERTEX,	// VkVertexInputStepRate	stepRate;
1026 	};
1027 
1028 	const VkVertexInputAttributeDescription vertexInputAttributeDescription =
1029 	{
1030 		0u,									// deUint32	location;
1031 		0u,									// deUint32	binding;
1032 		VK_FORMAT_R32G32_SFLOAT,			// VkFormat	format;
1033 		0u,									// deUint32	offsetInBytes;
1034 	};
1035 
1036 	const VkPipelineVertexInputStateCreateInfo	vertexInputStateParams =
1037 	{
1038 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
1039 		DE_NULL,														// const void*								pNext;
1040 		0,																// VkPipelineVertexInputStateCreateFlags	flags;
1041 		1u,																// deUint32									bindingCount;
1042 		&vertexInputBindingDescription,									// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
1043 		1u,																// deUint32									attributeCount;
1044 		&vertexInputAttributeDescription,								// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
1045 	};
1046 
1047 	const std::vector<VkViewport> viewports(1, {0, 0, WIDTH, HEIGHT, 0, 1});
1048 	const std::vector<VkRect2D> scissors(1, { {0, 0}, {WIDTH, HEIGHT} });
1049 	const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
1050 	{
1051 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType							sType;
1052 		DE_NULL,													// const void*								pNext;
1053 		0u,															// VkPipelineRasterizationStateCreateFlags	flags;
1054 		VK_FALSE,													// VkBool32									depthClampEnable;
1055 		VK_FALSE,													// VkBool32									rasterizerDiscardEnable;
1056 		VK_POLYGON_MODE_FILL,										// VkPolygonMode							polygonMode;
1057 		VK_CULL_MODE_NONE,											// VkCullModeFlags							cullMode;
1058 		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace								frontFace;
1059 		VK_FALSE,													// VkBool32									depthBiasEnable;
1060 		0.0f,														// float									depthBiasConstantFactor;
1061 		0.0f,														// float									depthBiasClamp;
1062 		0.0f,														// float									depthBiasSlopeFactor;
1063 		1.0f,														// float									lineWidth;
1064 	};
1065 	const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1066 	{
1067 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
1068 		DE_NULL,													// const void*								pNext;
1069 		0u,															// VkPipelineMultisampleStateCreateFlags	flags;
1070 		m_sampleCount,												// VkSampleCountFlagBits					rasterizationSamples;
1071 		VK_TRUE,													// VkBool32									sampleShadingEnable;
1072 		1.0f,														// float									minSampleShading;
1073 		DE_NULL,													// const VkSampleMask*						pSampleMask;
1074 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
1075 		VK_FALSE													// VkBool32									alphaToOneEnable;
1076 	};
1077 	std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(m_colorAttNum,
1078 		{
1079 			false,								// VkBool32				blendEnable;
1080 			VK_BLEND_FACTOR_ONE,				// VkBlend				srcBlendColor;
1081 			VK_BLEND_FACTOR_ONE,				// VkBlend				destBlendColor;
1082 			VK_BLEND_OP_ADD,					// VkBlendOp			blendOpColor;
1083 			VK_BLEND_FACTOR_ONE,				// VkBlend				srcBlendAlpha;
1084 			VK_BLEND_FACTOR_ONE,				// VkBlend				destBlendAlpha;
1085 			VK_BLEND_OP_ADD,					// VkBlendOp			blendOpAlpha;
1086 			(VK_COLOR_COMPONENT_R_BIT |
1087 			 VK_COLOR_COMPONENT_G_BIT)			// VkChannelFlags		channelWriteMask;
1088 		});
1089 
1090 	const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1091 	{
1092 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
1093 		DE_NULL,													// const void*									pNext;
1094 		/* always needed */
1095 		m_testCase->getBlendStateFlags(),							// VkPipelineColorBlendStateCreateFlags			flags;
1096 		false,														// VkBool32										logicOpEnable;
1097 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
1098 		(deUint32)colorBlendAttachmentState.size(),					// deUint32										attachmentCount;
1099 		colorBlendAttachmentState.data(),							// const VkPipelineColorBlendAttachmentState*	pAttachments;
1100 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConst[4];
1101 	};
1102 
1103 	VkStencilOpState stencilOpState =
1104 	{
1105 		VK_STENCIL_OP_ZERO,					// VkStencilOp	failOp;
1106 		VK_STENCIL_OP_INCREMENT_AND_WRAP,	// VkStencilOp	passOp;
1107 		VK_STENCIL_OP_INCREMENT_AND_WRAP,	// VkStencilOp	depthFailOp;
1108 		VK_COMPARE_OP_ALWAYS,				// VkCompareOp	compareOp;
1109 		0xff,								// uint32_t		compareMask;
1110 		0xff,								// uint32_t		writeMask;
1111 		0,									// uint32_t		reference;
1112 	};
1113 	VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1114 	{
1115 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1116 								// VkStructureType							sType;
1117 		DE_NULL,				// const void*								pNext;
1118 		m_testCase->getDSStateFlags(),
1119 								// VkPipelineDepthStencilStateCreateFlags	flags;
1120 		VK_TRUE,				// VkBool32									depthTestEnable;
1121 		VK_TRUE,				// VkBool32									depthWriteEnable;
1122 		VK_COMPARE_OP_ALWAYS,	// VkCompareOp								depthCompareOp;
1123 		VK_FALSE,				// VkBool32									depthBoundsTestEnable;
1124 		VK_TRUE,				// VkBool32									stencilTestEnable;
1125 		stencilOpState,			// VkStencilOpState							front;
1126 		stencilOpState,			// VkStencilOpState							back;
1127 		0.0f,					// float									minDepthBounds;
1128 		1.0f,					// float									maxDepthBounds;
1129 	};
1130 
1131 
1132 	m_pipeline = makeGraphicsPipeline(	vk,									// const DeviceInterface&							vk
1133 										device,								// const VkDevice									device
1134 										*m_pipelineLayout,					// const VkPipelineLayout							pipelineLayout
1135 										*vs,								// const VkShaderModule								vertexShaderModule
1136 										DE_NULL,							// const VkShaderModule								tessellationControlShaderModule
1137 										DE_NULL,							// const VkShaderModule								tessellationEvalShaderModule
1138 										DE_NULL,							// const VkShaderModule								geometryShaderModule
1139 										*fs,								// const VkShaderModule								fragmentShaderModule
1140 										renderPass,							// const VkRenderPass								renderPass
1141 										viewports,							// const std::vector<VkViewport>&					viewports
1142 										scissors,							// const std::vector<VkRect2D>&						scissors
1143 										VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,// const VkPrimitiveTopology						topology
1144 										m_subpass,							// const deUint32									subpass
1145 										0u,									// const deUint32									patchControlPoints
1146 										&vertexInputStateParams,			// const VkPipelineVertexInputStateCreateInfo*		vertexInputStateCreateInfo
1147 										&rasterizationStateInfo,			// const VkPipelineRasterizationStateCreateInfo*	rasterizationStateCreateInfo
1148 										&multisampleStateParams,			// const VkPipelineMultisampleStateCreateInfo*		multisampleStateCreateInfo
1149 										&depthStencilStateCreateInfo,		// const VkPipelineDepthStencilStateCreateInfo*		depthStencilStateCreateInfo,
1150 										&colorBlendStateParams,				// const VkPipelineColorBlendStateCreateInfo*		colorBlendStateCreateInfo,
1151 										DE_NULL);							// const VkPipelineDynamicStateCreateInfo*			dynamicStateCreateInfo
1152 }
1153 
makeSampler(const DeviceInterface & vk,const VkDevice & device)1154 static Move<VkSampler> makeSampler (const DeviceInterface& vk, const VkDevice& device)
1155 {
1156 	const VkSamplerCreateInfo createInfo =
1157 	{
1158 		VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// VkStructureType			sType;
1159 		DE_NULL,									// const void*				pNext;
1160 		0u,											// VkSamplerCreateFlags		flags;
1161 		VK_FILTER_NEAREST,							// VkFilter					magFilter;
1162 		VK_FILTER_NEAREST,							// VkFilter					minFilter;
1163 		VK_SAMPLER_MIPMAP_MODE_LINEAR,				// VkSamplerMipmapMode		mipmapMode;
1164 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeU;
1165 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeV;
1166 		VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// VkSamplerAddressMode		addressModeW;
1167 		0.0f,										// float					mipLodBias;
1168 		VK_FALSE,									// VkBool32					anisotropyEnable;
1169 		1.0f,										// float					maxAnisotropy;
1170 		VK_FALSE,									// VkBool32					compareEnable;
1171 		VK_COMPARE_OP_ALWAYS,						// VkCompareOp				compareOp;
1172 		0.0f,										// float					minLod;
1173 		0.0f,										// float					maxLod;
1174 		VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// VkBorderColor			borderColor;
1175 		VK_FALSE									// VkBool32					unnormalizedCoordinates;
1176 	};
1177 
1178 	return createSampler(vk, device, &createInfo);
1179 }
1180 
makeDescriptorSetLayout(const DeviceInterface & vk,const VkDevice device,deUint32 attNum)1181 static Move<VkDescriptorSetLayout> makeDescriptorSetLayout(const DeviceInterface &vk, const VkDevice device, deUint32 attNum)
1182 {
1183 	vector<VkDescriptorSetLayoutBinding>	bindings(attNum,
1184 	{
1185 		0,												// binding
1186 		VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,			// descriptorType
1187 		1u,												// descriptorCount
1188 		VK_SHADER_STAGE_FRAGMENT_BIT,					// stageFlags
1189 		DE_NULL,										// pImmutableSamplers
1190 	});
1191 	for (deUint32 i = 0; i < attNum; i++)
1192 	{
1193 		bindings[i].binding = i;
1194 	}
1195 
1196 	const VkDescriptorSetLayoutCreateInfo	layoutCreateInfo =
1197 	{
1198 		VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
1199 		DE_NULL,										// pNext
1200 		0u,												// flags
1201 		attNum,											// bindingCount
1202 		bindings.data(),								// pBindings
1203 	};
1204 
1205 	return vk::createDescriptorSetLayout(vk, device, &layoutCreateInfo);
1206 }
writeDescriptorSets()1207 void AttachmentAccessOrderTestInstance::writeDescriptorSets()
1208 {
1209 	deUint32 attNum = m_testCase->getInputAttachmentNum();
1210 	for (deUint32 i = 0 ; i < attNum ; i++ )
1211 	{
1212 		VkDescriptorImageInfo img_info = {};
1213 		img_info.sampler = *m_sampler;
1214 		img_info.imageView = *m_subpasses[0].m_inputAttView[i];
1215 		img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1216 
1217 		VkWriteDescriptorSet write = {};
1218 		write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
1219 		write.dstSet = *m_descSet;
1220 		write.dstBinding = i;
1221 		write.dstArrayElement = 0;
1222 		write.descriptorCount = 1;
1223 		write.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT;
1224 		write.pImageInfo = &img_info;
1225 
1226 		m_vk.updateDescriptorSets(m_context.getDevice(), 1u, &write, 0u, DE_NULL);
1227 	}
1228 }
1229 
addDependency(vector<VkSubpassDependency> & dependencies,deUint32 source,deUint32 dst,VkPipelineStageFlags pipelineFlags,VkAccessFlags accessFlags)1230 void AttachmentAccessOrderTestInstance::addDependency(	vector<VkSubpassDependency> &dependencies, deUint32 source, deUint32 dst,
1231 														VkPipelineStageFlags pipelineFlags, VkAccessFlags accessFlags)
1232 {
1233 	dependencies.push_back({
1234 		source,											//uint32_t					srcSubpass;
1235 		dst,											//uint32_t					dstSubpass;
1236 		pipelineFlags,									//VkPipelineStageFlags		srcStageMask;
1237 		VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,			//VkPipelineStageFlags		dstStageMask;
1238 		accessFlags,									//VkAccessFlags				srcAccessMask;
1239 		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,			//VkAccessFlags				dstAccessMask;
1240 		VK_DEPENDENCY_BY_REGION_BIT,					//VkDependencyFlags			dependencyFlags;
1241 	});
1242 }
createRenderPass(VkFormat attFormat)1243 Move<VkRenderPass> AttachmentAccessOrderTestInstance::createRenderPass(VkFormat attFormat)
1244 {
1245 	const VkDevice device = m_context.getDevice();
1246 	vector<VkAttachmentDescription> attachmentDescs;
1247 	for (deUint32 subpass = 0; subpass < 2; subpass ++)
1248 	{
1249 		for (deUint32 i = 0 ; i < m_subpasses[subpass].getInputAttachmentNum(); i++)
1250 		{
1251 			VkFormat format = attFormat;
1252 			if (i >= m_subpasses[subpass].getColorAttachmentNum())
1253 			{
1254 				format = m_testCase->checkAndGetDSFormat(m_context);
1255 				DE_ASSERT(format != VK_FORMAT_UNDEFINED);
1256 			}
1257 			attachmentDescs.push_back({
1258 				0,											// VkAttachmentDescriptionFlags		flags;
1259 				format,										// VkFormat							format;
1260 				m_subpasses[subpass].m_sampleCount,			// VkSampleCountFlagBits			samples;
1261 				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				loadOp;
1262 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				storeOp;
1263 				VK_ATTACHMENT_LOAD_OP_LOAD,					// VkAttachmentLoadOp				stencilLoadOp;
1264 				VK_ATTACHMENT_STORE_OP_STORE,				// VkAttachmentStoreOp				stencilStoreOp;
1265 				VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout					initialLayout;
1266 				VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout					finalLayout;
1267 			});
1268 		}
1269 	}
1270 
1271 	std::vector<VkSubpassDescription> subpasses(2, VkSubpassDescription{});
1272 
1273 	subpasses[0].pipelineBindPoint =	VK_PIPELINE_BIND_POINT_GRAPHICS;
1274 	subpasses[0].inputAttachmentCount = m_subpasses[0].getInputAttachmentNum();
1275 	subpasses[0].pInputAttachments =	m_subpasses[0].m_attachmentReferences.data();
1276 	subpasses[0].colorAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1277 	subpasses[0].pColorAttachments =	m_subpasses[0].m_attachmentReferences.data();
1278 	subpasses[0].pDepthStencilAttachment = m_subpasses[0].getDepthStencilAttachment();
1279 
1280 	subpasses[1].pipelineBindPoint =	VK_PIPELINE_BIND_POINT_GRAPHICS;
1281 	subpasses[1].inputAttachmentCount = m_subpasses[0].getColorAttachmentNum();
1282 	subpasses[1].pInputAttachments =	m_subpasses[0].m_attachmentReferences.data();
1283 	subpasses[1].colorAttachmentCount = m_subpasses[1].getColorAttachmentNum();
1284 	subpasses[1].pColorAttachments =	m_subpasses[1].m_attachmentReferences.data();
1285 
1286 	/* self dependency for subpass 0 and dependency from subpass 0 to 1 */
1287 	vector<VkSubpassDependency> dependencies;
1288 	addDependency(dependencies, 0, 1, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1289 	if (m_testCase->m_explicitSync)
1290 	{
1291 		addDependency(dependencies, 0, 0, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1292 		if (m_testCase->hasDepthStencil())
1293 		{
1294 			const auto fragTests = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1295 			addDependency(dependencies, 0, 0, fragTests, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
1296 		}
1297 	}
1298 	else
1299 	{
1300 		subpasses[0].flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM;
1301 		subpasses[1].flags = VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_COLOR_ACCESS_BIT_ARM;
1302 		if (m_testCase->hasDepth())
1303 		{
1304 			subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1305 			subpasses[1].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1306 		}
1307 		else if (m_testCase->hasStencil())
1308 		{
1309 			subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1310 			subpasses[1].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1311 		}
1312 	}
1313 
1314 	VkRenderPassCreateInfo renderPassCreateInfo =
1315 	{
1316 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
1317 		NULL,											// const void*						pNext;
1318 		0,												// VkRenderPassCreateFlags			flags;
1319 		(deUint32)attachmentDescs.size(),				// uint32_t							attachmentCount;
1320 		attachmentDescs.data(),							// const VkAttachmentDescription*	pAttachments;
1321 		(deUint32)subpasses.size(),						// uint32_t							subpassCount;
1322 		subpasses.data(),								// const VkSubpassDescription*		pSubpasses;
1323 		(deUint32)dependencies.size(),					// uint32_t							dependencyCount;
1324 		dependencies.data(),							// const VkSubpassDependency*		pDependencies;
1325 	};
1326 
1327 	return ::createRenderPass(m_vk, device, &renderPassCreateInfo);
1328 }
1329 
createVertexBuffer()1330 void AttachmentAccessOrderTestInstance::createVertexBuffer()
1331 {
1332 	deUint32 primitiveNum = m_testCase->m_overlapPrimitives ? AttachmentAccessOrderTestCase::ELEM_NUM * 2: 2;
1333 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1334 	const VkDevice device = m_context.getDevice();
1335 	Allocator& allocator = m_context.getDefaultAllocator();
1336 	std::vector<tcu::Vec2> vbo(3*primitiveNum);
1337 	for (deUint32 i=0; i < primitiveNum/2; i++)
1338 	{
1339 		vbo[i*6 + 0] = {-1, -1};
1340 		vbo[i*6 + 1] = { 1, -1};
1341 		vbo[i*6 + 2] = {-1,  1};
1342 		vbo[i*6 + 3] = { 1,  1};
1343 		vbo[i*6 + 4] = {-1,  1};
1344 		vbo[i*6 + 5] = { 1, -1};
1345 	}
1346 
1347 	const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1348 	{
1349 		const VkBufferCreateInfo vertexBufferParams =
1350 		{
1351 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1352 			DE_NULL,								// const void*			pNext;
1353 			0u,										// VkBufferCreateFlags	flags;
1354 			dataSize,								// VkDeviceSize			size;
1355 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
1356 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1357 			1u,										// deUint32				queueFamilyCount;
1358 			&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
1359 		};
1360 		m_vertexBuffer = createBuffer(m_vk, device, &vertexBufferParams);
1361 		m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(m_vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1362 
1363 		VK_CHECK(m_vk.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
1364 	}
1365 
1366 	/* Load vertices into vertex buffer */
1367 	deMemcpy(m_vertexBufferMemory->getHostPtr(), vbo.data(), dataSize);
1368 	flushAlloc(m_vk, device, *m_vertexBufferMemory);
1369 }
1370 
createResultBuffer()1371 void AttachmentAccessOrderTestInstance::createResultBuffer()
1372 {
1373 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1374 	const VkDevice device = m_context.getDevice();
1375 	Allocator& allocator = m_context.getDefaultAllocator();
1376 	/* result buffer */
1377 	const VkBufferCreateInfo					resultBufferInfo		=
1378 	{
1379 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1380 		DE_NULL,								// const void*			pNext;
1381 		0u,										// VkBufferCreateFlags	flags;
1382 		WIDTH * HEIGHT * sizeof(tcu::UVec2),	// VkDeviceSize			size;
1383 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
1384 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1385 		1u,										// deUint32				queueFamilyCount;
1386 		&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
1387 	};
1388 	m_resultBuffer = createBuffer(m_vk, device, &resultBufferInfo);
1389 	m_resultBufferMemory = allocator.allocate(	getBufferMemoryRequirements(m_vk, device, *m_resultBuffer), MemoryRequirement::HostVisible);
1390 
1391 	VK_CHECK(m_vk.bindBufferMemory(device, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
1392 }
1393 
AttachmentAccessOrderTestInstance(Context & context,const AttachmentAccessOrderTestCase * testCase)1394 AttachmentAccessOrderTestInstance::AttachmentAccessOrderTestInstance( Context& context, const AttachmentAccessOrderTestCase *testCase)
1395 	: TestInstance(context)
1396 	, m_testCase (testCase)
1397 	, m_vk (m_context.getDeviceInterface())
1398 	, m_subpasses(2)
1399 {
1400 	const VkDevice device = m_context.getDevice();
1401 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1402 
1403 	m_descSetLayout = makeDescriptorSetLayout(m_vk, device, m_testCase->getInputAttachmentNum());
1404 
1405 	m_descPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_testCase->getInputAttachmentNum())
1406 		.build(m_vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1407 
1408 	m_descSet = makeDescriptorSet(m_vk, device, *m_descPool, *m_descSetLayout, nullptr);
1409 
1410 	vector<VkImageView> attachmentHandles;
1411 	VkDescriptorSetLayout dsetLayout = *m_descSetLayout;
1412 
1413 	m_subpasses[0].createAttachments(	0, m_testCase->getInputAttachmentNum(), m_testCase->getColorAttachmentNum(), m_testCase->m_sampleCount,
1414 										m_context, attachmentHandles, &dsetLayout, m_testCase);
1415 	m_subpasses[1].createAttachments(1, 1, 1, VK_SAMPLE_COUNT_1_BIT, m_context, attachmentHandles, &dsetLayout, m_testCase);
1416 
1417 	m_sampler = makeSampler(m_vk, device);
1418 
1419 	writeDescriptorSets();
1420 	m_renderPass = createRenderPass(m_testCase->getColorFormat());
1421 
1422 	m_framebuffer = makeFramebuffer(m_vk, device, *m_renderPass, (deUint32)attachmentHandles.size(), attachmentHandles.data(), WIDTH, HEIGHT, 1);
1423 
1424 	m_subpasses[0].createPipeline(*m_renderPass, m_context);
1425 	m_subpasses[1].createPipeline(*m_renderPass, m_context);
1426 
1427 	createVertexBuffer();
1428 
1429 	createResultBuffer();
1430 
1431 	m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1432 	m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1433 }
1434 
~AttachmentAccessOrderTestInstance(void)1435 AttachmentAccessOrderTestInstance::~AttachmentAccessOrderTestInstance (void)
1436 {
1437 }
1438 
addPipelineBarrier(VkCommandBuffer cmdBuffer,VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkImageAspectFlags aspect)1439 void AttachmentAccessOrderTestInstance::addPipelineBarrier(	VkCommandBuffer			cmdBuffer,
1440 															VkImage					image,
1441 															VkImageLayout			oldLayout,
1442 															VkImageLayout			newLayout,
1443 															VkAccessFlags			srcAccessMask,
1444 															VkAccessFlags			dstAccessMask,
1445 															VkPipelineStageFlags	srcStageMask,
1446 															VkPipelineStageFlags	dstStageMask,
1447 															VkImageAspectFlags		aspect)
1448 {
1449 	VkImageMemoryBarrier barrier =
1450 	{
1451 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1452 		DE_NULL,									// const void*				pNext;
1453 		srcAccessMask,								// VkAccessFlags			srcAccessMask;
1454 		dstAccessMask,								// VkAccessFlags			dstAccessMask;
1455 		oldLayout,									// VkImageLayout			oldLayout;
1456 		newLayout,									// VkImageLayout			newLayout;
1457 		VK_QUEUE_FAMILY_IGNORED,					// uint32_t					srcQueueFamilyIndex;
1458 		VK_QUEUE_FAMILY_IGNORED,					// uint32_t					dstQueueFamilyIndex;
1459 		image,										// VkImage					image;
1460 		{
1461 			aspect,						//VkImageAspectFlags	aspectMask;
1462 			0u,							//uint32_t				baseMipLevel;
1463 			1u,							//uint32_t				levelCount;
1464 			0u,							//uint32_t				baseArrayLayer;
1465 			1u,							//uint32_t				layerCount;
1466 		},											// VkImageSubresourceRange	subresourceRange;
1467 	};
1468 
1469 	m_vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, VK_DEPENDENCY_BY_REGION_BIT,
1470 							0, nullptr, 0, nullptr, 1, &barrier);
1471 }
addClearColor(VkCommandBuffer cmdBuffer,VkImage image)1472 void AttachmentAccessOrderTestInstance::addClearColor(VkCommandBuffer cmdBuffer, VkImage image)
1473 {
1474 	VkClearColorValue clearColor;
1475 	clearColor.float32[0] = 0.0;
1476 	clearColor.float32[1] = 0.0;
1477 	clearColor.float32[2] = 0.0;
1478 	clearColor.float32[3] = 1.0;
1479 
1480 	const VkImageSubresourceRange subresourceRange =
1481 	{
1482 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
1483 		0u,							//uint32_t				baseMipLevel;
1484 		1u,							//uint32_t				levelCount;
1485 		0u,							//uint32_t				baseArrayLayer;
1486 		1u,							//uint32_t				layerCount;
1487 	};
1488 
1489 	m_vk.cmdClearColorImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
1490 }
1491 
addClearDepthStencil(VkCommandBuffer cmdBuffer,VkImage image)1492 void AttachmentAccessOrderTestInstance::addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image)
1493 {
1494 	VkClearDepthStencilValue clearValue;
1495 	clearValue.depth = 0.0;
1496 	clearValue.stencil = 0;
1497 
1498 	const VkImageSubresourceRange subresourceRange =
1499 	{
1500 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//VkImageAspectFlags	aspectMask;
1501 		0u,															//uint32_t				baseMipLevel;
1502 		1u,															//uint32_t				levelCount;
1503 		0u,															//uint32_t				baseArrayLayer;
1504 		1u,															//uint32_t				layerCount;
1505 	};
1506 
1507 	m_vk.cmdClearDepthStencilImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &subresourceRange);
1508 }
1509 
1510 
iterate(void)1511 tcu::TestStatus AttachmentAccessOrderTestInstance::iterate (void)
1512 {
1513 	const VkQueue queue = m_context.getUniversalQueue();
1514 	const VkDevice device = m_context.getDevice();
1515 
1516 	beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
1517 
1518 	for (deUint32 i=0; i < m_subpasses.size(); i++)
1519 	{
1520 		for (deUint32 j=0; j < m_subpasses[i].getColorAttachmentNum(); j++)
1521 		{
1522 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1523 								0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1524 
1525 			addClearColor( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1526 		}
1527 		for (deUint32 j=m_subpasses[i].getColorAttachmentNum(); j < m_subpasses[i].getInputAttachmentNum(); j++)
1528 		{
1529 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1530 								0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1531 								VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1532 			addClearDepthStencil( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1533 		}
1534 	}
1535 
1536 	const VkMemoryBarrier memBarrier =
1537 	{
1538 		VK_STRUCTURE_TYPE_MEMORY_BARRIER,
1539 		DE_NULL,
1540 		VK_ACCESS_TRANSFER_WRITE_BIT,
1541 		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1542 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
1543 	};
1544 
1545 	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1546 							0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1547 
1548 	const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
1549 	beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
1550 
1551 	const VkDeviceSize vertexBufferOffset = 0;
1552 	const VkBuffer vertexBuffer = *m_vertexBuffer;
1553 
1554 	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1555 	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipeline);
1556 	VkDescriptorSet dset = *m_descSet;
1557 	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1558 
1559 	deUint32 numDraws = m_testCase->m_overlapDraws ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1560 	deUint32 numPrimitives = m_testCase->m_overlapPrimitives ? 2 * AttachmentAccessOrderTestCase::ELEM_NUM : 2;
1561 	deUint32 numInstances = m_testCase->m_overlapInstances ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1562 
1563 	for (deUint32 i=0; i < numDraws; i++)
1564 	{
1565 		m_vk.cmdPushConstants(	*m_cmdBuffer, *m_subpasses[0].m_pipelineLayout,
1566 								VK_SHADER_STAGE_FRAGMENT_BIT | (m_testCase->hasDepthStencil() ? VK_SHADER_STAGE_VERTEX_BIT : 0),
1567 								0, 4, &i);
1568 		for (deUint32 j = 0; m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getColorAttachmentNum(); j++)
1569 		{
1570 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1571 								VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1572 								VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1573 								VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1574 		}
1575 		for (deUint32 j = m_subpasses[0].getColorAttachmentNum(); m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getInputAttachmentNum(); j++)
1576 		{
1577 			const auto fragTests = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1578 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1579 								VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1580 								VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1581 								fragTests, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1582 								VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1583 		}
1584 		m_vk.cmdDraw(*m_cmdBuffer, numPrimitives * 3, numInstances, 0, 0);
1585 	}
1586 
1587 
1588 	m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1589 
1590 	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipeline);
1591 
1592 	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1593 
1594 	m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 0, 0);
1595 
1596 	endRenderPass(m_vk, *m_cmdBuffer);
1597 
1598 	copyImageToBuffer(	m_vk, *m_cmdBuffer, *m_subpasses[1].m_inputAtt[0], *m_resultBuffer, tcu::IVec2(WIDTH, HEIGHT), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1599 						VK_IMAGE_LAYOUT_GENERAL);
1600 
1601 	endCommandBuffer(m_vk, *m_cmdBuffer);
1602 
1603 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1604 
1605 	return validateResults(numDraws, numPrimitives, numInstances);
1606 }
1607 
validateResults(deUint32 numDraws,deUint32 numPrimitives,deUint32 numInstances)1608 tcu::TestStatus AttachmentAccessOrderTestInstance::validateResults(deUint32 numDraws, deUint32 numPrimitives, deUint32 numInstances)
1609 {
1610 	const VkDevice device = m_context.getDevice();
1611 	qpTestResult res = QP_TEST_RESULT_PASS;
1612 
1613 	invalidateAlloc(m_vk, device, *m_resultBufferMemory);
1614 	if (m_testCase->m_integerFormat)
1615 	{
1616 		tcu::UVec2 *resBuf = static_cast<tcu::UVec2 *> (m_resultBufferMemory->getHostPtr());
1617 
1618 		for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1619 		{
1620 			for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1621 			{
1622 				tcu::UVec2 pixel = resBuf[y * WIDTH + x];
1623 				if (pixel[0] != 0 || pixel[1] != numDraws * numPrimitives/2 * numInstances)
1624 				{
1625 					res = QP_TEST_RESULT_FAIL;
1626 				}
1627 			}
1628 		}
1629 	}
1630 	else
1631 	{
1632 		tcu::Vec2 *resBuf = static_cast<tcu::Vec2 *> (m_resultBufferMemory->getHostPtr());
1633 
1634 		for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1635 		{
1636 			for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1637 			{
1638 				tcu::Vec2 pixel = resBuf[y * WIDTH + x];
1639 				if (pixel[0] != 0 || pixel[1] != (float)(numDraws * numPrimitives/2 * numInstances))
1640 				{
1641 					res = QP_TEST_RESULT_FAIL;
1642 				}
1643 			}
1644 		}
1645 	}
1646 
1647 	return tcu::TestStatus(res, qpGetTestResultName(res));
1648 }
1649 
1650 
1651 } // anonymous ns
1652 
1653 
createRasterizationOrderAttachmentAccessTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,const string & prefix_name,const string & prefix_desc,deUint32 inputNum,bool integerFormat,bool depth,bool stencil)1654 static void createRasterizationOrderAttachmentAccessTestVariations(	tcu::TestContext& testCtx, tcu::TestCaseGroup *gr,
1655 																	const string &prefix_name, const string &prefix_desc,
1656 																	deUint32 inputNum, bool integerFormat, bool depth, bool stencil)
1657 {
1658 	const struct
1659 	{
1660 		const std::string name;
1661 		const std::string description;
1662 		bool explicitSync;
1663 		bool overlapDraws;
1664 		bool overlapPrimitives;
1665 		bool overlapInstances;
1666 	} leafTestCreateParams[] =
1667 	{
1668 		{ "multi_draw_barriers",	"Basic test with overlapping draw commands with barriers",								true,  true,  false, false,	},
1669 		{ "multi_draw",				"Test with overlapping draw commands without barriers",									false, true,  false, false,	},
1670 		{ "multi_primitives",		"Test with a draw command with overlapping primitives",									false, false, true,  false,	},
1671 		{ "multi_instances",		"Test with a draw command with overlapping instances",									false, false, false, true,	},
1672 		{ "all",					"Test with overlapping draw commands, each with overlapping primitives and instances",	false, true,  true,  true,	},
1673 	};
1674 	constexpr deUint32 leafTestCreateParamsNum = sizeof(leafTestCreateParams) / sizeof(leafTestCreateParams[0]);
1675 
1676 	VkSampleCountFlagBits sampleCountValues[] =
1677 	{
1678 		VK_SAMPLE_COUNT_1_BIT,
1679 		VK_SAMPLE_COUNT_2_BIT,
1680 		VK_SAMPLE_COUNT_4_BIT,
1681 		VK_SAMPLE_COUNT_8_BIT,
1682 		VK_SAMPLE_COUNT_16_BIT,
1683 		VK_SAMPLE_COUNT_32_BIT,
1684 		VK_SAMPLE_COUNT_64_BIT,
1685 	};
1686 	constexpr deUint32 sampleCountValuesNum = sizeof(sampleCountValues) / sizeof(sampleCountValues[0]);
1687 
1688 	for (deUint32 i = 0; i < sampleCountValuesNum ; i++)
1689 	{
1690 		stringstream name;
1691 		stringstream desc;
1692 		name << prefix_name << "samples_" << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]);
1693 		desc << prefix_desc << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]) << " samples per pixel";
1694 		tcu::TestCaseGroup *subgr = new tcu::TestCaseGroup(testCtx, name.str().c_str(), desc.str().c_str());
1695 
1696 		for (deUint32 k = 0; k < leafTestCreateParamsNum; k++)
1697 		{
1698 			if (depth)
1699 			{
1700 				subgr->addChild(new AttachmentAccessOrderDepthTestCase(	testCtx, leafTestCreateParams[k].name,
1701 																		leafTestCreateParams[k].description,
1702 																		leafTestCreateParams[k].explicitSync,
1703 																		leafTestCreateParams[k].overlapDraws,
1704 																		leafTestCreateParams[k].overlapPrimitives,
1705 																		leafTestCreateParams[k].overlapInstances,
1706 																		sampleCountValues[i]));
1707 			}
1708 			else if (stencil)
1709 			{
1710 				subgr->addChild(new AttachmentAccessOrderStencilTestCase(	testCtx, leafTestCreateParams[k].name,
1711 																			leafTestCreateParams[k].description,
1712 																			leafTestCreateParams[k].explicitSync,
1713 																			leafTestCreateParams[k].overlapDraws,
1714 																			leafTestCreateParams[k].overlapPrimitives,
1715 																			leafTestCreateParams[k].overlapInstances,
1716 																			sampleCountValues[i]));
1717 			}
1718 			else
1719 			{
1720 				subgr->addChild(new AttachmentAccessOrderColorTestCase(	testCtx, leafTestCreateParams[k].name,
1721 																		leafTestCreateParams[k].description,
1722 																		leafTestCreateParams[k].explicitSync,
1723 																		leafTestCreateParams[k].overlapDraws,
1724 																		leafTestCreateParams[k].overlapPrimitives,
1725 																		leafTestCreateParams[k].overlapInstances,
1726 																		sampleCountValues[i], inputNum, integerFormat));
1727 			}
1728 		}
1729 		gr->addChild(subgr);
1730 	}
1731 }
1732 
createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,bool integerFormat)1733 static void createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *gr, bool integerFormat)
1734 {
1735 	const deUint32 inputNum[] = {1, 4, 8};
1736 	const deUint32 inputNumSize = sizeof(inputNum) / sizeof(inputNum[0]);
1737 
1738 	tcu::TestCaseGroup *formatGr;
1739 
1740 	if (integerFormat)
1741 	{
1742 		formatGr = new tcu::TestCaseGroup(testCtx, "format_integer", "Tests with an integer format" );
1743 	}
1744 	else
1745 	{
1746 		formatGr = new tcu::TestCaseGroup(testCtx, "format_float", "Tests with an float format" );
1747 	}
1748 
1749 	for (deUint32 i = 0; i < inputNumSize; i++)
1750 	{
1751 		stringstream numName;
1752 		stringstream numDesc;
1753 		numName << "attachments_" << inputNum[i] << "_";
1754 		numDesc << "Tests with " << inputNum[i] << " attachments and ";
1755 		createRasterizationOrderAttachmentAccessTestVariations(testCtx, formatGr, numName.str(), numDesc.str(), inputNum[i], integerFormat, false, false);
1756 	}
1757 	gr->addChild(formatGr);
1758 }
1759 
createRasterizationOrderAttachmentAccessTests(tcu::TestContext & testCtx)1760 tcu::TestCaseGroup* createRasterizationOrderAttachmentAccessTests(tcu::TestContext& testCtx)
1761 {
1762 	/* Add the color tests */
1763 	tcu::TestCaseGroup *gr = new tcu::TestCaseGroup(testCtx, "rasterization_order_attachment_access", "Rasterization Order Attachment access tests");
1764 	createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, false);
1765 	createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, true);
1766 
1767 	/* Add the D/S tests */
1768 	tcu::TestCaseGroup *depth_gr = new tcu::TestCaseGroup(testCtx, "depth", "Tests depth rasterization order" );
1769 	tcu::TestCaseGroup *stencil_gr = new tcu::TestCaseGroup(testCtx, "stencil", "Tests stencil rasterization order" );
1770 	string name_prefix = "";
1771 	string desc_prefix = "Tests with ";
1772 	createRasterizationOrderAttachmentAccessTestVariations(testCtx, depth_gr, name_prefix, desc_prefix, 1, false, true, false);
1773 	createRasterizationOrderAttachmentAccessTestVariations(testCtx, stencil_gr, name_prefix, desc_prefix, 1, false, false, true);
1774 	gr->addChild(depth_gr);
1775 	gr->addChild(stencil_gr);
1776 
1777 	return gr;
1778 }
1779 
1780 } // rasterization
1781 } // vkt
1782