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