• 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 		if (m_testCase->hasDepth())
1302 		{
1303 			subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_DEPTH_ACCESS_BIT_ARM;
1304 		}
1305 		else if (m_testCase->hasStencil())
1306 		{
1307 			subpasses[0].flags |= VK_SUBPASS_DESCRIPTION_RASTERIZATION_ORDER_ATTACHMENT_STENCIL_ACCESS_BIT_ARM;
1308 		}
1309 	}
1310 
1311 	VkRenderPassCreateInfo renderPassCreateInfo =
1312 	{
1313 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// VkStructureType					sType;
1314 		NULL,											// const void*						pNext;
1315 		0,												// VkRenderPassCreateFlags			flags;
1316 		(deUint32)attachmentDescs.size(),				// uint32_t							attachmentCount;
1317 		attachmentDescs.data(),							// const VkAttachmentDescription*	pAttachments;
1318 		(deUint32)subpasses.size(),						// uint32_t							subpassCount;
1319 		subpasses.data(),								// const VkSubpassDescription*		pSubpasses;
1320 		(deUint32)dependencies.size(),					// uint32_t							dependencyCount;
1321 		dependencies.data(),							// const VkSubpassDependency*		pDependencies;
1322 	};
1323 
1324 	return ::createRenderPass(m_vk, device, &renderPassCreateInfo);
1325 }
1326 
createVertexBuffer()1327 void AttachmentAccessOrderTestInstance::createVertexBuffer()
1328 {
1329 	deUint32 primitiveNum = m_testCase->m_overlapPrimitives ? AttachmentAccessOrderTestCase::ELEM_NUM * 2: 2;
1330 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1331 	const VkDevice device = m_context.getDevice();
1332 	Allocator& allocator = m_context.getDefaultAllocator();
1333 	std::vector<tcu::Vec2> vbo(3*primitiveNum);
1334 	for (deUint32 i=0; i < primitiveNum/2; i++)
1335 	{
1336 		vbo[i*6 + 0] = {-1, -1};
1337 		vbo[i*6 + 1] = { 1, -1};
1338 		vbo[i*6 + 2] = {-1,  1};
1339 		vbo[i*6 + 3] = { 1,  1};
1340 		vbo[i*6 + 4] = {-1,  1};
1341 		vbo[i*6 + 5] = { 1, -1};
1342 	}
1343 
1344 	const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1345 	{
1346 		const VkBufferCreateInfo vertexBufferParams =
1347 		{
1348 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1349 			DE_NULL,								// const void*			pNext;
1350 			0u,										// VkBufferCreateFlags	flags;
1351 			dataSize,								// VkDeviceSize			size;
1352 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// VkBufferUsageFlags	usage;
1353 			VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1354 			1u,										// deUint32				queueFamilyCount;
1355 			&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
1356 		};
1357 		m_vertexBuffer = createBuffer(m_vk, device, &vertexBufferParams);
1358 		m_vertexBufferMemory = allocator.allocate(getBufferMemoryRequirements(m_vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible);
1359 
1360 		VK_CHECK(m_vk.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferMemory->getMemory(), m_vertexBufferMemory->getOffset()));
1361 	}
1362 
1363 	/* Load vertices into vertex buffer */
1364 	deMemcpy(m_vertexBufferMemory->getHostPtr(), vbo.data(), dataSize);
1365 	flushAlloc(m_vk, device, *m_vertexBufferMemory);
1366 }
1367 
createResultBuffer()1368 void AttachmentAccessOrderTestInstance::createResultBuffer()
1369 {
1370 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1371 	const VkDevice device = m_context.getDevice();
1372 	Allocator& allocator = m_context.getDefaultAllocator();
1373 	/* result buffer */
1374 	const VkBufferCreateInfo					resultBufferInfo		=
1375 	{
1376 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// VkStructureType		sType;
1377 		DE_NULL,								// const void*			pNext;
1378 		0u,										// VkBufferCreateFlags	flags;
1379 		WIDTH * HEIGHT * sizeof(tcu::UVec2),	// VkDeviceSize			size;
1380 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,		// VkBufferUsageFlags	usage;
1381 		VK_SHARING_MODE_EXCLUSIVE,				// VkSharingMode		sharingMode;
1382 		1u,										// deUint32				queueFamilyCount;
1383 		&queueFamilyIndex						// const deUint32*		pQueueFamilyIndices;
1384 	};
1385 	m_resultBuffer = createBuffer(m_vk, device, &resultBufferInfo);
1386 	m_resultBufferMemory = allocator.allocate(	getBufferMemoryRequirements(m_vk, device, *m_resultBuffer), MemoryRequirement::HostVisible);
1387 
1388 	VK_CHECK(m_vk.bindBufferMemory(device, *m_resultBuffer, m_resultBufferMemory->getMemory(), m_resultBufferMemory->getOffset()));
1389 }
1390 
AttachmentAccessOrderTestInstance(Context & context,const AttachmentAccessOrderTestCase * testCase)1391 AttachmentAccessOrderTestInstance::AttachmentAccessOrderTestInstance( Context& context, const AttachmentAccessOrderTestCase *testCase)
1392 	: TestInstance(context)
1393 	, m_testCase (testCase)
1394 	, m_vk (m_context.getDeviceInterface())
1395 	, m_subpasses(2)
1396 {
1397 	const VkDevice device = m_context.getDevice();
1398 	const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1399 
1400 	m_descSetLayout = makeDescriptorSetLayout(m_vk, device, m_testCase->getInputAttachmentNum());
1401 
1402 	m_descPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_testCase->getInputAttachmentNum())
1403 		.build(m_vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1404 
1405 	m_descSet = makeDescriptorSet(m_vk, device, *m_descPool, *m_descSetLayout, nullptr);
1406 
1407 	vector<VkImageView> attachmentHandles;
1408 	VkDescriptorSetLayout dsetLayout = *m_descSetLayout;
1409 
1410 	m_subpasses[0].createAttachments(	0, m_testCase->getInputAttachmentNum(), m_testCase->getColorAttachmentNum(), m_testCase->m_sampleCount,
1411 										m_context, attachmentHandles, &dsetLayout, m_testCase);
1412 	m_subpasses[1].createAttachments(1, 1, 1, VK_SAMPLE_COUNT_1_BIT, m_context, attachmentHandles, &dsetLayout, m_testCase);
1413 
1414 	m_sampler = makeSampler(m_vk, device);
1415 
1416 	writeDescriptorSets();
1417 	m_renderPass = createRenderPass(m_testCase->getColorFormat());
1418 
1419 	m_framebuffer = makeFramebuffer(m_vk, device, *m_renderPass, (deUint32)attachmentHandles.size(), attachmentHandles.data(), WIDTH, HEIGHT, 1);
1420 
1421 	m_subpasses[0].createPipeline(*m_renderPass, m_context);
1422 	m_subpasses[1].createPipeline(*m_renderPass, m_context);
1423 
1424 	createVertexBuffer();
1425 
1426 	createResultBuffer();
1427 
1428 	m_cmdPool = createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1429 	m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1430 }
1431 
~AttachmentAccessOrderTestInstance(void)1432 AttachmentAccessOrderTestInstance::~AttachmentAccessOrderTestInstance (void)
1433 {
1434 }
1435 
addPipelineBarrier(VkCommandBuffer cmdBuffer,VkImage image,VkImageLayout oldLayout,VkImageLayout newLayout,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkImageAspectFlags aspect)1436 void AttachmentAccessOrderTestInstance::addPipelineBarrier(	VkCommandBuffer			cmdBuffer,
1437 															VkImage					image,
1438 															VkImageLayout			oldLayout,
1439 															VkImageLayout			newLayout,
1440 															VkAccessFlags			srcAccessMask,
1441 															VkAccessFlags			dstAccessMask,
1442 															VkPipelineStageFlags	srcStageMask,
1443 															VkPipelineStageFlags	dstStageMask,
1444 															VkImageAspectFlags		aspect)
1445 {
1446 	VkImageMemoryBarrier barrier =
1447 	{
1448 		VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
1449 		DE_NULL,									// const void*				pNext;
1450 		srcAccessMask,								// VkAccessFlags			srcAccessMask;
1451 		dstAccessMask,								// VkAccessFlags			dstAccessMask;
1452 		oldLayout,									// VkImageLayout			oldLayout;
1453 		newLayout,									// VkImageLayout			newLayout;
1454 		VK_QUEUE_FAMILY_IGNORED,					// uint32_t					srcQueueFamilyIndex;
1455 		VK_QUEUE_FAMILY_IGNORED,					// uint32_t					dstQueueFamilyIndex;
1456 		image,										// VkImage					image;
1457 		{
1458 			aspect,						//VkImageAspectFlags	aspectMask;
1459 			0u,							//uint32_t				baseMipLevel;
1460 			1u,							//uint32_t				levelCount;
1461 			0u,							//uint32_t				baseArrayLayer;
1462 			1u,							//uint32_t				layerCount;
1463 		},											// VkImageSubresourceRange	subresourceRange;
1464 	};
1465 
1466 	m_vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, VK_DEPENDENCY_BY_REGION_BIT,
1467 							0, nullptr, 0, nullptr, 1, &barrier);
1468 }
addClearColor(VkCommandBuffer cmdBuffer,VkImage image)1469 void AttachmentAccessOrderTestInstance::addClearColor(VkCommandBuffer cmdBuffer, VkImage image)
1470 {
1471 	VkClearColorValue clearColor;
1472 	clearColor.float32[0] = 0.0;
1473 	clearColor.float32[1] = 0.0;
1474 	clearColor.float32[2] = 0.0;
1475 	clearColor.float32[3] = 1.0;
1476 
1477 	const VkImageSubresourceRange subresourceRange =
1478 	{
1479 		VK_IMAGE_ASPECT_COLOR_BIT,	//VkImageAspectFlags	aspectMask;
1480 		0u,							//uint32_t				baseMipLevel;
1481 		1u,							//uint32_t				levelCount;
1482 		0u,							//uint32_t				baseArrayLayer;
1483 		1u,							//uint32_t				layerCount;
1484 	};
1485 
1486 	m_vk.cmdClearColorImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearColor, 1, &subresourceRange);
1487 }
1488 
addClearDepthStencil(VkCommandBuffer cmdBuffer,VkImage image)1489 void AttachmentAccessOrderTestInstance::addClearDepthStencil(VkCommandBuffer cmdBuffer, VkImage image)
1490 {
1491 	VkClearDepthStencilValue clearValue;
1492 	clearValue.depth = 0.0;
1493 	clearValue.stencil = 0;
1494 
1495 	const VkImageSubresourceRange subresourceRange =
1496 	{
1497 		VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT,	//VkImageAspectFlags	aspectMask;
1498 		0u,															//uint32_t				baseMipLevel;
1499 		1u,															//uint32_t				levelCount;
1500 		0u,															//uint32_t				baseArrayLayer;
1501 		1u,															//uint32_t				layerCount;
1502 	};
1503 
1504 	m_vk.cmdClearDepthStencilImage(cmdBuffer, image, VK_IMAGE_LAYOUT_GENERAL, &clearValue, 1, &subresourceRange);
1505 }
1506 
1507 
iterate(void)1508 tcu::TestStatus AttachmentAccessOrderTestInstance::iterate (void)
1509 {
1510 	const VkQueue queue = m_context.getUniversalQueue();
1511 	const VkDevice device = m_context.getDevice();
1512 
1513 	beginCommandBuffer(m_vk, *m_cmdBuffer, 0u);
1514 
1515 	for (deUint32 i=0; i < m_subpasses.size(); i++)
1516 	{
1517 		for (deUint32 j=0; j < m_subpasses[i].getColorAttachmentNum(); j++)
1518 		{
1519 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1520 								0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
1521 
1522 			addClearColor( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1523 		}
1524 		for (deUint32 j=m_subpasses[i].getColorAttachmentNum(); j < m_subpasses[i].getInputAttachmentNum(); j++)
1525 		{
1526 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[i].m_inputAtt[j], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL,
1527 								0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1528 								VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1529 			addClearDepthStencil( *m_cmdBuffer, *m_subpasses[i].m_inputAtt[j]);
1530 		}
1531 	}
1532 
1533 	const VkMemoryBarrier memBarrier =
1534 	{
1535 		VK_STRUCTURE_TYPE_MEMORY_BARRIER,
1536 		DE_NULL,
1537 		VK_ACCESS_TRANSFER_WRITE_BIT,
1538 		VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
1539 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
1540 	};
1541 
1542 	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
1543 							0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1544 
1545 	const VkRect2D renderArea = makeRect2D(WIDTH, HEIGHT);
1546 	beginRenderPass(m_vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
1547 
1548 	const VkDeviceSize vertexBufferOffset = 0;
1549 	const VkBuffer vertexBuffer = *m_vertexBuffer;
1550 
1551 	m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1552 	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipeline);
1553 	VkDescriptorSet dset = *m_descSet;
1554 	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[0].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1555 
1556 	deUint32 numDraws = m_testCase->m_overlapDraws ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1557 	deUint32 numPrimitives = m_testCase->m_overlapPrimitives ? 2 * AttachmentAccessOrderTestCase::ELEM_NUM : 2;
1558 	deUint32 numInstances = m_testCase->m_overlapInstances ? AttachmentAccessOrderTestCase::ELEM_NUM : 1;
1559 
1560 	for (deUint32 i=0; i < numDraws; i++)
1561 	{
1562 		m_vk.cmdPushConstants(	*m_cmdBuffer, *m_subpasses[0].m_pipelineLayout,
1563 								VK_SHADER_STAGE_FRAGMENT_BIT | (m_testCase->hasDepthStencil() ? VK_SHADER_STAGE_VERTEX_BIT : 0),
1564 								0, 4, &i);
1565 		for (deUint32 j = 0; m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getColorAttachmentNum(); j++)
1566 		{
1567 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1568 								VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1569 								VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1570 								VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1571 		}
1572 		for (deUint32 j = m_subpasses[0].getColorAttachmentNum(); m_testCase->m_explicitSync && i != 0 && j < m_subpasses[0].getInputAttachmentNum(); j++)
1573 		{
1574 			const auto fragTests = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1575 			addPipelineBarrier(	*m_cmdBuffer, *m_subpasses[0].m_inputAtt[j], VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL,
1576 								VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1577 								VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
1578 								fragTests, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1579 								VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
1580 		}
1581 		m_vk.cmdDraw(*m_cmdBuffer, numPrimitives * 3, numInstances, 0, 0);
1582 	}
1583 
1584 
1585 	m_vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
1586 
1587 	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipeline);
1588 
1589 	m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_subpasses[1].m_pipelineLayout, 0, 1, &dset, 0, DE_NULL);
1590 
1591 	m_vk.cmdDraw(*m_cmdBuffer, 6, 1, 0, 0);
1592 
1593 	endRenderPass(m_vk, *m_cmdBuffer);
1594 
1595 	copyImageToBuffer(	m_vk, *m_cmdBuffer, *m_subpasses[1].m_inputAtt[0], *m_resultBuffer, tcu::IVec2(WIDTH, HEIGHT), VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1596 						VK_IMAGE_LAYOUT_GENERAL);
1597 
1598 	endCommandBuffer(m_vk, *m_cmdBuffer);
1599 
1600 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1601 
1602 	return validateResults(numDraws, numPrimitives, numInstances);
1603 }
1604 
validateResults(deUint32 numDraws,deUint32 numPrimitives,deUint32 numInstances)1605 tcu::TestStatus AttachmentAccessOrderTestInstance::validateResults(deUint32 numDraws, deUint32 numPrimitives, deUint32 numInstances)
1606 {
1607 	const VkDevice device = m_context.getDevice();
1608 	qpTestResult res = QP_TEST_RESULT_PASS;
1609 
1610 	invalidateAlloc(m_vk, device, *m_resultBufferMemory);
1611 	if (m_testCase->m_integerFormat)
1612 	{
1613 		tcu::UVec2 *resBuf = static_cast<tcu::UVec2 *> (m_resultBufferMemory->getHostPtr());
1614 
1615 		for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1616 		{
1617 			for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1618 			{
1619 				tcu::UVec2 pixel = resBuf[y * WIDTH + x];
1620 				if (pixel[0] != 0 || pixel[1] != numDraws * numPrimitives/2 * numInstances)
1621 				{
1622 					res = QP_TEST_RESULT_FAIL;
1623 				}
1624 			}
1625 		}
1626 	}
1627 	else
1628 	{
1629 		tcu::Vec2 *resBuf = static_cast<tcu::Vec2 *> (m_resultBufferMemory->getHostPtr());
1630 
1631 		for (deUint32 y = 0; y < HEIGHT && res == QP_TEST_RESULT_PASS; y ++)
1632 		{
1633 			for (deUint32 x = 0; x < WIDTH && res == QP_TEST_RESULT_PASS; x ++)
1634 			{
1635 				tcu::Vec2 pixel = resBuf[y * WIDTH + x];
1636 				if (pixel[0] != 0 || pixel[1] != (float)(numDraws * numPrimitives/2 * numInstances))
1637 				{
1638 					res = QP_TEST_RESULT_FAIL;
1639 				}
1640 			}
1641 		}
1642 	}
1643 
1644 	return tcu::TestStatus(res, qpGetTestResultName(res));
1645 }
1646 
1647 
1648 } // anonymous ns
1649 
1650 
createRasterizationOrderAttachmentAccessTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,const string & prefix_name,const string & prefix_desc,deUint32 inputNum,bool integerFormat,bool depth,bool stencil)1651 static void createRasterizationOrderAttachmentAccessTestVariations(	tcu::TestContext& testCtx, tcu::TestCaseGroup *gr,
1652 																	const string &prefix_name, const string &prefix_desc,
1653 																	deUint32 inputNum, bool integerFormat, bool depth, bool stencil)
1654 {
1655 	const struct
1656 	{
1657 		const std::string name;
1658 		const std::string description;
1659 		bool explicitSync;
1660 		bool overlapDraws;
1661 		bool overlapPrimitives;
1662 		bool overlapInstances;
1663 	} leafTestCreateParams[] =
1664 	{
1665 		{ "multi_draw_barriers",	"Basic test with overlapping draw commands with barriers",								true,  true,  false, false,	},
1666 		{ "multi_draw",				"Test with overlapping draw commands without barriers",									false, true,  false, false,	},
1667 		{ "multi_primitives",		"Test with a draw command with overlapping primitives",									false, false, true,  false,	},
1668 		{ "multi_instances",		"Test with a draw command with overlapping instances",									false, false, false, true,	},
1669 		{ "all",					"Test with overlapping draw commands, each with overlapping primitives and instances",	false, true,  true,  true,	},
1670 	};
1671 	constexpr deUint32 leafTestCreateParamsNum = sizeof(leafTestCreateParams) / sizeof(leafTestCreateParams[0]);
1672 
1673 	VkSampleCountFlagBits sampleCountValues[] =
1674 	{
1675 		VK_SAMPLE_COUNT_1_BIT,
1676 		VK_SAMPLE_COUNT_2_BIT,
1677 		VK_SAMPLE_COUNT_4_BIT,
1678 		VK_SAMPLE_COUNT_8_BIT,
1679 		VK_SAMPLE_COUNT_16_BIT,
1680 		VK_SAMPLE_COUNT_32_BIT,
1681 		VK_SAMPLE_COUNT_64_BIT,
1682 	};
1683 	constexpr deUint32 sampleCountValuesNum = sizeof(sampleCountValues) / sizeof(sampleCountValues[0]);
1684 
1685 	for (deUint32 i = 0; i < sampleCountValuesNum ; i++)
1686 	{
1687 		stringstream name;
1688 		stringstream desc;
1689 		name << prefix_name << "samples_" << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]);
1690 		desc << prefix_desc << AttachmentAccessOrderTestCase::getSampleNum(sampleCountValues[i]) << " samples per pixel";
1691 		tcu::TestCaseGroup *subgr = new tcu::TestCaseGroup(testCtx, name.str().c_str(), desc.str().c_str());
1692 
1693 		for (deUint32 k = 0; k < leafTestCreateParamsNum; k++)
1694 		{
1695 			if (depth)
1696 			{
1697 				subgr->addChild(new AttachmentAccessOrderDepthTestCase(	testCtx, leafTestCreateParams[k].name,
1698 																		leafTestCreateParams[k].description,
1699 																		leafTestCreateParams[k].explicitSync,
1700 																		leafTestCreateParams[k].overlapDraws,
1701 																		leafTestCreateParams[k].overlapPrimitives,
1702 																		leafTestCreateParams[k].overlapInstances,
1703 																		sampleCountValues[i]));
1704 			}
1705 			else if (stencil)
1706 			{
1707 				subgr->addChild(new AttachmentAccessOrderStencilTestCase(	testCtx, leafTestCreateParams[k].name,
1708 																			leafTestCreateParams[k].description,
1709 																			leafTestCreateParams[k].explicitSync,
1710 																			leafTestCreateParams[k].overlapDraws,
1711 																			leafTestCreateParams[k].overlapPrimitives,
1712 																			leafTestCreateParams[k].overlapInstances,
1713 																			sampleCountValues[i]));
1714 			}
1715 			else
1716 			{
1717 				subgr->addChild(new AttachmentAccessOrderColorTestCase(	testCtx, leafTestCreateParams[k].name,
1718 																		leafTestCreateParams[k].description,
1719 																		leafTestCreateParams[k].explicitSync,
1720 																		leafTestCreateParams[k].overlapDraws,
1721 																		leafTestCreateParams[k].overlapPrimitives,
1722 																		leafTestCreateParams[k].overlapInstances,
1723 																		sampleCountValues[i], inputNum, integerFormat));
1724 			}
1725 		}
1726 		gr->addChild(subgr);
1727 	}
1728 }
1729 
createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr,bool integerFormat)1730 static void createRasterizationOrderAttachmentAccessFormatTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *gr, bool integerFormat)
1731 {
1732 	const deUint32 inputNum[] = {1, 4, 8};
1733 	const deUint32 inputNumSize = sizeof(inputNum) / sizeof(inputNum[0]);
1734 
1735 	tcu::TestCaseGroup *formatGr;
1736 
1737 	if (integerFormat)
1738 	{
1739 		formatGr = new tcu::TestCaseGroup(testCtx, "format_integer", "Tests with an integer format" );
1740 	}
1741 	else
1742 	{
1743 		formatGr = new tcu::TestCaseGroup(testCtx, "format_float", "Tests with an float format" );
1744 	}
1745 
1746 	for (deUint32 i = 0; i < inputNumSize; i++)
1747 	{
1748 		stringstream numName;
1749 		stringstream numDesc;
1750 		numName << "attachments_" << inputNum[i] << "_";
1751 		numDesc << "Tests with " << inputNum[i] << " attachments and ";
1752 		createRasterizationOrderAttachmentAccessTestVariations(testCtx, formatGr, numName.str(), numDesc.str(), inputNum[i], integerFormat, false, false);
1753 	}
1754 	gr->addChild(formatGr);
1755 }
1756 
createRasterizationOrderAttachmentAccessTests(tcu::TestContext & testCtx)1757 tcu::TestCaseGroup* createRasterizationOrderAttachmentAccessTests(tcu::TestContext& testCtx)
1758 {
1759 	/* Add the color tests */
1760 	tcu::TestCaseGroup *gr = new tcu::TestCaseGroup(testCtx, "rasterization_order_attachment_access", "Rasterization Order Attachment access tests");
1761 	createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, false);
1762 	createRasterizationOrderAttachmentAccessFormatTests(testCtx, gr, true);
1763 
1764 	/* Add the D/S tests */
1765 	tcu::TestCaseGroup *depth_gr = new tcu::TestCaseGroup(testCtx, "depth", "Tests depth rasterization order" );
1766 	tcu::TestCaseGroup *stencil_gr = new tcu::TestCaseGroup(testCtx, "stencil", "Tests stencil rasterization order" );
1767 	string name_prefix = "";
1768 	string desc_prefix = "Tests with ";
1769 	createRasterizationOrderAttachmentAccessTestVariations(testCtx, depth_gr, name_prefix, desc_prefix, 1, false, true, false);
1770 	createRasterizationOrderAttachmentAccessTestVariations(testCtx, stencil_gr, name_prefix, desc_prefix, 1, false, false, true);
1771 	gr->addChild(depth_gr);
1772 	gr->addChild(stencil_gr);
1773 
1774 	return gr;
1775 }
1776 
1777 } // rasterization
1778 } // vkt
1779