• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2022 The Khronos Group Inc.
6  * Copyright (c) 2022 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_EXT_shader_tile_image tests.
23  *//*--------------------------------------------------------------------*/
24 
25 // Draw overwrapped patches with incremental value. The last value should be the patch count.
26 // Decision is made with comparing between simulated value and result value.
27 // All multi sample tests run with per sample shading property except MsaaSampleMask test case.
28 // There are several variants.
29 //  - Color
30 //  - Depth
31 //  - Stencil
32 //  - Msaa
33 //  - Formats
34 //  - Draw Count
35 //  - Patch Count per Draw
36 //  - Coherent Mode
37 //  ...
38 
39 #include "vktShaderTileImageTests.hpp"
40 #include "deDefs.hpp"
41 #include "deSharedPtr.hpp"
42 #include "deUniquePtr.hpp"
43 #include "draw/vktDrawBufferObjectUtil.hpp"
44 #include "tcuCommandLine.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuResource.hpp"
47 #include "tcuStringTemplate.hpp"
48 #include "tcuTestLog.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "vkBuilderUtil.hpp"
51 #include "vkCmdUtil.hpp"
52 #include "vkDefs.hpp"
53 #include "vkImageUtil.hpp"
54 #include "vkMemUtil.hpp"
55 #include "vkObjUtil.hpp"
56 #include "vkPrograms.hpp"
57 #include "vkQueryUtil.hpp"
58 #include "vkRef.hpp"
59 #include "vkRefUtil.hpp"
60 #include "vkTypeUtil.hpp"
61 #include "vktRasterizationTests.hpp"
62 #include "vktTestCase.hpp"
63 
64 using namespace vk;
65 using de::MovePtr;
66 using de::SharedPtr;
67 
68 namespace vkt
69 {
70 
71 namespace rasterization
72 {
73 
74 namespace
75 {
76 
77 constexpr deUint32 kImageSize			   = 4; // power of 2 for helper test
78 constexpr deUint32 kMultiDrawElementCount  = 3;
79 constexpr deUint32 kMultiPatchElementCount = 3;
80 constexpr deUint32 kMRTCount			   = 2;
81 constexpr uint32_t kDerivative0			   = 1; // derivative 0 + offset 1
82 constexpr uint32_t kDerivative1			   = 2; // derivative 1 + offset 1
83 
84 enum class TestType
85 {
86 	Color,
87 	MultiRenderTarget,
88 	MultiRenderTargetDynamicIndex,
89 	MsaaSampleMask,
90 	HelperClassColor,
91 	HelperClassDepth,
92 	HelperClassStencil,
93 	Depth,
94 	Stencil
95 };
96 
97 struct TestParam
98 {
99 	bool				  coherent;
100 	TestType			  testType;
101 	VkFormat			  colorFormat;
102 	VkFormat			  depthStencilFormat;
103 	VkSampleCountFlagBits m_sampleCount;
104 	bool				  multipleDrawCalls;
105 	bool				  multiplePatchesPerDraw;
106 	deUint32			  frameBufferSize;
107 };
108 
isHelperClassTest(TestType testType)109 bool isHelperClassTest(TestType testType)
110 {
111 	const bool helperClass = (testType == TestType::HelperClassColor) || (testType == TestType::HelperClassDepth) ||
112 							 (testType == TestType::HelperClassStencil);
113 	return helperClass;
114 }
115 
getSampleCount(VkSampleCountFlagBits sampleCount)116 deUint32 getSampleCount(VkSampleCountFlagBits sampleCount)
117 {
118 	deUint32 ret = 0;
119 	switch (sampleCount)
120 	{
121 	case VK_SAMPLE_COUNT_1_BIT:
122 		ret = 1;
123 		break;
124 	case VK_SAMPLE_COUNT_2_BIT:
125 		ret = 2;
126 		break;
127 	case VK_SAMPLE_COUNT_4_BIT:
128 		ret = 4;
129 		break;
130 	case VK_SAMPLE_COUNT_8_BIT:
131 		ret = 8;
132 		break;
133 	case VK_SAMPLE_COUNT_16_BIT:
134 		ret = 16;
135 		break;
136 	case VK_SAMPLE_COUNT_32_BIT:
137 		ret = 32;
138 		break;
139 	case VK_SAMPLE_COUNT_64_BIT:
140 		ret = 64;
141 		break;
142 	default:
143 		DE_ASSERT(false);
144 	};
145 	return ret;
146 }
147 
getSampleMask(TestType testType)148 deUint32 getSampleMask(TestType testType)
149 {
150 	return (testType == TestType::MsaaSampleMask) ? 0xaaaaaaaa : 0;
151 }
152 
getColorAttachmentCount(TestType testType)153 deUint32 getColorAttachmentCount(TestType testType)
154 {
155 	switch (testType)
156 	{
157 	case TestType::MultiRenderTargetDynamicIndex:
158 	case TestType::MultiRenderTarget:
159 	case TestType::HelperClassColor:
160 	case TestType::HelperClassDepth:
161 	case TestType::HelperClassStencil:
162 		return kMRTCount;
163 	default:
164 		return 1;
165 	}
166 	return 1;
167 }
168 
getVertexCountPerPatch(const TestParam * testParam)169 deUint32 getVertexCountPerPatch(const TestParam* testParam)
170 {
171 	return (testParam->testType == TestType::MsaaSampleMask) ? 3 : 6;
172 }
173 
getPatchesPerDrawCount(bool multiplePatchesPerDraw)174 deUint32 getPatchesPerDrawCount(bool multiplePatchesPerDraw)
175 {
176 	return multiplePatchesPerDraw ? kMultiPatchElementCount : 1;
177 }
178 
getDrawCallCount(const TestParam * testParam)179 deUint32 getDrawCallCount(const TestParam* testParam)
180 {
181 	if (isHelperClassTest(testParam->testType))
182 	{
183 		// helper class use two draw calls, but it is similar to single draw call
184 		DE_ASSERT(!testParam->multipleDrawCalls);
185 		return 2;
186 	}
187 
188 	return testParam->multipleDrawCalls ? kMultiDrawElementCount : 1;
189 }
190 
isNormalizedColorFormat(VkFormat format)191 bool isNormalizedColorFormat(VkFormat format)
192 {
193 	const tcu::TextureFormat	   colorFormat(mapVkFormat(format));
194 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
195 	const bool normalizedColorFormat = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
196 										channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT);
197 	return normalizedColorFormat;
198 }
199 
addOverhead(std::stringstream & shaderStream)200 void addOverhead(std::stringstream& shaderStream)
201 {
202 	shaderStream << "{\n"
203 				 << "	uint overheadLoop = uint(gl_FragCoord.x) * uint(${TOTAL_PATCH_COUNT} + 1);\n"
204 				 << "	zero = patchIndex / (${TOTAL_PATCH_COUNT} + 1);\n"
205 				 << "	for(uint index = 0u; index < overheadLoop; index++)\n"
206 				 << "	{\n"
207 				 << "		zero = uint(sin(float(zero)));\n"
208 				 << "	}\n"
209 				 << "}\n";
210 }
211 
transition2DImage(const vk::DeviceInterface & vk,vk::VkCommandBuffer cmdBuffer,vk::VkImage image,vk::VkImageAspectFlags aspectMask,vk::VkImageLayout oldLayout,vk::VkImageLayout newLayout,vk::VkAccessFlags srcAccessMask,vk::VkAccessFlags dstAccessMask,vk::VkPipelineStageFlags srcStageMask,vk::VkPipelineStageFlags dstStageMask)212 void transition2DImage(const vk::DeviceInterface& vk, vk::VkCommandBuffer cmdBuffer, vk::VkImage image,
213 					   vk::VkImageAspectFlags aspectMask, vk::VkImageLayout oldLayout, vk::VkImageLayout newLayout,
214 					   vk::VkAccessFlags srcAccessMask, vk::VkAccessFlags dstAccessMask,
215 					   vk::VkPipelineStageFlags srcStageMask, vk::VkPipelineStageFlags dstStageMask)
216 {
217 	vk::VkImageMemoryBarrier barrier;
218 	barrier.sType							= vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
219 	barrier.pNext							= DE_NULL;
220 	barrier.srcAccessMask					= srcAccessMask;
221 	barrier.dstAccessMask					= dstAccessMask;
222 	barrier.oldLayout						= oldLayout;
223 	barrier.newLayout						= newLayout;
224 	barrier.srcQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;
225 	barrier.dstQueueFamilyIndex				= VK_QUEUE_FAMILY_IGNORED;
226 	barrier.image							= image;
227 	barrier.subresourceRange.aspectMask		= aspectMask;
228 	barrier.subresourceRange.baseMipLevel	= 0;
229 	barrier.subresourceRange.levelCount		= 1;
230 	barrier.subresourceRange.baseArrayLayer = 0;
231 	barrier.subresourceRange.layerCount		= 1;
232 
233 	vk.cmdPipelineBarrier(cmdBuffer, srcStageMask, dstStageMask, (vk::VkDependencyFlags)0, 0,
234 						  (const vk::VkMemoryBarrier*)DE_NULL, 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1,
235 						  &barrier);
236 }
237 
238 class ShaderTileImageTestCase : public TestCase
239 {
240 public:
241 	ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam);
242 	~ShaderTileImageTestCase() override = default;
243 	TestInstance* createInstance(Context& context) const override;
244 
245 protected:
246 	void initPrograms(SourceCollections& programCollection) const override;
247 	void checkSupport(Context& context) const override;
248 
249 	void addVS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
250 	void addFS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
251 	void addCS(SourceCollections& programCollection, const std::map<std::string, std::string>& params) const;
252 
253 	void getColorTestTypeFS(std::stringstream& fragShader) const;
254 	void getHelperClassTestTypeFS(std::stringstream& fragShader) const;
255 	void getSampleMaskTypeFS(std::stringstream& fragShader) const;
256 	void getDepthTestTypeFS(std::stringstream& fragShader) const;
257 	void getStencilTestTypeFS(std::stringstream& fragShader) const;
258 
259 protected:
260 	const TestParam m_testParam;
261 };
262 
263 class ShaderTileImageTestInstance : public TestInstance
264 {
265 public:
266 	ShaderTileImageTestInstance(Context& context, const TestParam* testParam);
267 	~ShaderTileImageTestInstance() override = default;
268 	tcu::TestStatus iterate() override;
269 
270 protected:
271 	void			 initialize();
272 	void			 generateCmdBuffer();
273 	void			 generateVertexBuffer();
274 	void			 generateAttachments();
275 	Move<VkPipeline> generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite,
276 											  bool disableStencilWrite);
277 	void			 generateComputePipeline();
278 	void			 rendering();
279 	deUint32		 getResultValue(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const;
280 	deUint32		 simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const;
281 	tcu::TestStatus	 checkResult() const;
282 
283 protected:
284 	const TestParam* m_testParam;
285 
286 	const DeviceInterface&	m_vk;
287 	SharedPtr<Draw::Buffer> m_vertexBuffer;
288 
289 	Move<VkCommandPool>				m_cmdPool;
290 	Move<VkCommandBuffer>			m_cmdBuffer;
291 	Move<vk::VkDescriptorPool>		m_descriptorPool;
292 	Move<vk::VkDescriptorSet>		m_descriptorSets[kMRTCount];
293 	Move<VkPipelineLayout>			m_graphicsPipelineLayout;
294 	Move<VkPipeline>				m_graphicsPipeline;
295 	Move<VkPipeline>				m_graphicsPipelineForHelperClass;
296 	Move<vk::VkDescriptorSetLayout> m_computeDescriptorSetLayout;
297 	Move<VkPipelineLayout>			m_computePipelineLayout;
298 	Move<VkPipeline>				m_computePipeline;
299 	Move<VkShaderModule>			m_vertexModule;
300 	Move<VkShaderModule>			m_fragmentModule;
301 	Move<VkImage>					m_imageColor[kMRTCount];
302 	MovePtr<Allocation>				m_imageColorAlloc[kMRTCount];
303 	deUint32*						m_imageColorBufferHostPtr;
304 	Move<VkImageView>				m_imageColorView[kMRTCount];
305 	SharedPtr<Draw::Buffer>			m_imageBuffer[kMRTCount];
306 	Move<VkImage>					m_imageDepthStencil;
307 	MovePtr<Allocation>				m_imageDepthStencilAlloc;
308 	Move<VkImageView>				m_imageDepthStencilView;
309 };
310 
ShaderTileImageTestCase(tcu::TestContext & context,const std::string & name,const TestParam & testParam)311 ShaderTileImageTestCase::ShaderTileImageTestCase(tcu::TestContext& context, const std::string& name, const TestParam& testParam)
312 	: TestCase(context, name), m_testParam(testParam)
313 {
314 }
315 
addVS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const316 void ShaderTileImageTestCase::addVS(SourceCollections&						  programCollection,
317 									const std::map<std::string, std::string>& params) const
318 {
319 	std::stringstream vertShader;
320 	vertShader << "#version 450 core\n"
321 			   << "precision highp float;\n"
322 			   << "precision highp int;\n"
323 			   << "layout(location = 0) in highp vec2 v_position;\n"
324 			   << "layout(location = 0) flat out uint patchIndex;"
325 			   << "layout( push_constant ) uniform ConstBlock\n"
326 			   << "{\n"
327 			   << "	highp uint drawIndex;\n"
328 			   << "};\n"
329 			   << "void main ()\n"
330 			   << "{\n"
331 			   << "	uint localPatchIndex = uint(gl_VertexIndex) / ${VERTEX_COUNT_PER_PATCH} + 1;\n" // index from 1
332 			   << "	uint patchCountPerDraw = ${PATCH_COUNT_PER_DRAW};\n"
333 			   << "	uint globalPatchIndex = drawIndex * patchCountPerDraw + localPatchIndex;\n"
334 			   << "	patchIndex = globalPatchIndex;\n"
335 			   << "	gl_Position = vec4(v_position, ${INV_TOTAL_PATCH_COUNT} * globalPatchIndex, 1);\n"
336 			   << "}\n";
337 
338 	tcu::StringTemplate vertShaderTpl(vertShader.str());
339 	programCollection.glslSources.add("vert") << glu::VertexSource(vertShaderTpl.specialize(params));
340 }
341 
getColorTestTypeFS(std::stringstream & fragShader) const342 void ShaderTileImageTestCase::getColorTestTypeFS(std::stringstream& fragShader) const
343 {
344 	const deUint32 attachmentCount		   = getColorAttachmentCount(m_testParam.testType);
345 	const bool	   mrtDynamicIndexTestType = (m_testParam.testType == TestType::MultiRenderTargetDynamicIndex);
346 	const bool	   multiSampleTest		   = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
347 
348 	const tcu::TextureFormat	   colorFormat(mapVkFormat(m_testParam.colorFormat));
349 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
350 	const bool					   normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
351 	const tcu::IVec4			   channelBitDepth		 = tcu::getTextureFormatBitDepth(colorFormat);
352 
353 	fragShader << "#version 450 core\n"
354 			   << "#extension GL_EXT_shader_tile_image : require\n"
355 			   << "precision highp float;\n"
356 			   << "precision highp int;\n"
357 			   << "layout( push_constant ) uniform ConstBlock\n"
358 			   << "{\n"
359 			   << "	highp uint drawIndex;\n"
360 			   << "};\n"
361 			   << "layout( location = 0 ) flat in uint patchIndex;\n";
362 
363 	if (!m_testParam.coherent)
364 	{
365 		fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
366 	}
367 
368 	if (mrtDynamicIndexTestType)
369 	{
370 		// layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn[0]
371 		fragShader << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn[${ATTACHMENT_COUNT}];\n";
372 	}
373 	else
374 	{
375 		for (deUint32 i = 0; i < attachmentCount; i++)
376 		{
377 			// layout( location = 0 ) tileImageEXT highp attachmentEXT colorIn0
378 			fragShader << "layout( location = " << i << ") tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn" << i << ";\n";
379 		}
380 	}
381 
382 	for (deUint32 i = 0; i < attachmentCount; i++)
383 	{
384 		// layout( location = 0 ) out highp vec4 out0
385 		fragShader << "layout( location = " << i << " ) out highp ${OUTPUT_VECTOR_NAME} out" << i << ";\n";
386 	}
387 
388 	fragShader << "void main()\n"
389 			   << "{\n"
390 			   << "	uint zero = 0;\n"
391 			   << "	uvec2 previous[${ATTACHMENT_COUNT}];\n";
392 
393 	float amplifier = 1.0f;
394 	if (normalizedColorFormat)
395 	{
396 		amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
397 						static_cast<float>(1 << (channelBitDepth.y() - 1)) : // signed
398 						static_cast<float>((1 << channelBitDepth.y()) - 1);	 // unsigned
399 
400 		// color output precision is less than test case;
401 		DE_ASSERT(amplifier > static_cast<float>(kMultiPatchElementCount * kMultiDrawElementCount * attachmentCount +
402 												 getSampleCount(m_testParam.m_sampleCount)));
403 	}
404 
405 	for (deUint32 i = 0; i < attachmentCount; i++)
406 	{
407 		// in0 or colorIn[0]
408 		const std::string inputImage =
409 			mrtDynamicIndexTestType ? "colorIn[" + std::to_string(i) + "]" : "colorIn" + std::to_string(i);
410 
411 		// (in0) or (colorIn0, gl_SampleID)
412 		const std::string funcParams = multiSampleTest ? "(" + inputImage + ", gl_SampleID)" : "(" + inputImage + ")";
413 
414 		if (normalizedColorFormat)
415 		{
416 			// previous[0] = round(colorAttachmentRead(in0) *  amplifier).xy;\n";
417 			fragShader << "	previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << " * "
418 					   << amplifier << ").xy));\n";
419 		}
420 		else
421 		{
422 			// previous[0] *= uvec2(round(colorAttachmentRead(in0).xy));\n";
423 			fragShader << "	previous[" << i << "] = uvec2(round((colorAttachmentReadEXT" << funcParams << ").xy));\n";
424 		}
425 	}
426 
427 	// add overhead after fetching data
428 	addOverhead(fragShader);
429 
430 	// used only for normalized color format
431 	const float invAmplifier = 1.0f / static_cast<float>(amplifier);
432 
433 	// write output
434 	for (deUint32 i = 0; i < attachmentCount; i++)
435 	{
436 		// if (previous[0].x == 0 && patchIndex == 1)", initial write
437 		//  out0.y = float(patchIndex + zero + gl_SampleID +  0);"
438 		// else if (previous[0].x == 0 && (previous[0].y + 1) == (patchIndex + gl_SampleID + 0))"
439 		//  out0.y = float(previous[0].y + 1);"
440 		// else
441 		//  out0.y = float(previous[0].y);"
442 		//  out0.x = 1;" // error
443 		fragShader << "	if (previous[" << i << "].x == 0 && patchIndex == 1)\n"
444 				   << "	{\n"
445 				   << "		out" << i << ".y = ${OUTPUT_BASIC_TYPE}(patchIndex + zero + gl_SampleID + " << i << ");\n"
446 				   << "	}\n"
447 				   << "	else if (previous[" << i << "].x == 0 && (previous[" << i
448 				   << "].y + 1) == (patchIndex + gl_SampleID + " << i << "))\n"
449 				   << "	{\n"
450 				   << "		out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y + 1 + zero);\n"
451 				   << "	}\n"
452 				   << "	else\n"
453 				   << "	{\n"
454 				   << "		out" << i << ".y = ${OUTPUT_BASIC_TYPE}(previous[" << i << "].y);\n" // for debug purpose
455 				   << "		out" << i << ".x = 1;\n"											 // error
456 				   << "	}\n";
457 
458 		if (normalizedColorFormat)
459 		{
460 			// out0.y *= invAmplifier;
461 			fragShader << "		out" << i << ".y *= " << invAmplifier << ";\n";
462 		}
463 	}
464 	fragShader << "}\n";
465 }
466 
getHelperClassTestTypeFS(std::stringstream & fragShader) const467 void ShaderTileImageTestCase::getHelperClassTestTypeFS(std::stringstream& fragShader) const
468 {
469 	const bool depthHelperClassTest	  = (m_testParam.testType == TestType::HelperClassDepth);
470 	const bool stencilHelperClassTest = (m_testParam.testType == TestType::HelperClassStencil);
471 
472 	DE_ASSERT(getPatchesPerDrawCount(!m_testParam.multiplePatchesPerDraw));
473 	DE_ASSERT(getDrawCallCount(&m_testParam) == 2);
474 	DE_ASSERT(getColorAttachmentCount(m_testParam.testType) == 2);
475 	DE_ASSERT((m_testParam.m_sampleCount == VK_SAMPLE_COUNT_1_BIT));
476 	DE_ASSERT(!isNormalizedColorFormat(m_testParam.colorFormat));
477 
478 	fragShader << "#version 450 core\n"
479 			   << "#extension GL_EXT_shader_tile_image : require\n"
480 			   << "precision highp float;\n"
481 			   << "precision highp int;\n"
482 			   << "layout( push_constant ) uniform ConstBlock\n"
483 			   << "{\n"
484 			   << "	highp uint drawIndex;\n"
485 			   << "};\n"
486 			   << "layout( location = 0 ) flat in uint patchIndex;\n";
487 
488 	if (!m_testParam.coherent)
489 	{
490 		fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
491 		if (depthHelperClassTest)
492 		{
493 			fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n";
494 		}
495 
496 		if (stencilHelperClassTest)
497 		{
498 			fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n";
499 		}
500 	}
501 
502 	fragShader << "layout(location = 0) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n";
503 	fragShader << "layout(location = 1) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn1;\n";
504 
505 	fragShader << "layout(location = 0) out highp ${OUTPUT_VECTOR_NAME} out0;\n";
506 	fragShader << "layout(location = 1) out highp ${OUTPUT_VECTOR_NAME} out1;\n";
507 
508 	fragShader << "void main()\n"
509 			   << "{\n"
510 			   << "	uint zero = 0;\n"
511 			   << "	uvec2 previous;\n";
512 
513 	if (depthHelperClassTest)
514 	{
515 		fragShader << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n";
516 		fragShader << "	previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n";		// read error status
517 		fragShader << "	previous.y = uint(round(depthAttachmentReadEXT() * scalingFactor));\n"; // read depth value
518 	}
519 	else if (stencilHelperClassTest)
520 	{
521 		fragShader << "	previous.x = uint(round(colorAttachmentReadEXT(colorIn0).x));\n"; // read error status
522 		fragShader << "	previous.y = uint(stencilAttachmentReadEXT());\n";				  // read stencil value
523 	}
524 	else
525 	{
526 		fragShader << "	previous = uvec2(round((colorAttachmentReadEXT(colorIn0)).xy));\n";
527 	}
528 
529 	{
530 		// draw only one triangle for helperClassTestType, dx or dy should be 0 inside of triangle.
531 		// And they should be patchIndex in the diagonal edge of triangle.
532 		fragShader << "	uint err = 0;\n"
533 				   << "	uint dx = 0;\n"
534 				   << "	uint dy = 0;\n"
535 				   << "	if (patchIndex != 1)"
536 				   << "	{\n"
537 				   << "		dx = uint(round(abs(dFdxFine(previous.y))));\n"
538 				   << "		dy = uint(round(abs(dFdyFine(previous.y))));\n"
539 				   << "		uint err = 0;\n"
540 				   << "		if ((dx != 0 && dx != patchIndex - 1) || (dy != 0 && dy != patchIndex - 1))\n"
541 				   << "		{\n"
542 				   << "			err = 1;\n" // first draw doesn't have error check.
543 				   << "		}\n"
544 				   << "	}\n";
545 	}
546 
547 	// add overhead after fetching data
548 	addOverhead(fragShader);
549 
550 	// first draw writes to attachment0
551 	// second draw reads from attachment0(depth) writes to attachment1
552 	{
553 		fragShader << "	if (patchIndex == 1 && err != 1)\n"
554 				   << "	{\n"
555 				   << "		out0.y = ${OUTPUT_BASIC_TYPE}(patchIndex);\n"
556 				   << "		out0.x = 0;\n" // error
557 				   << "	}\n"
558 				   << "	else if (previous.x == 0 && err != 1 && ((previous.y + 1) == patchIndex || previous.y == 0))\n"
559 				   << "	{\n"
560 				   << "		out1.y = ${OUTPUT_BASIC_TYPE}(max(dx, dy) + 1);\n" // last 1 is to differentiate clear value
561 				   << "	}\n"
562 				   << "	else\n"
563 				   << "	{\n"
564 				   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previous.y);\n" // for debug purpose
565 				   << "		out0.x = 1;\n"								  // error
566 				   << "		out1.y = ${OUTPUT_BASIC_TYPE}(previous.x);\n"
567 				   << "		out1.x = 1;\n" // error
568 				   << "	}\n";
569 	}
570 	fragShader << "}\n";
571 }
572 
getSampleMaskTypeFS(std::stringstream & fragShader) const573 void ShaderTileImageTestCase::getSampleMaskTypeFS(std::stringstream& fragShader) const
574 {
575 	const deUint32 sampleCount = getSampleCount(m_testParam.m_sampleCount);
576 
577 	const tcu::TextureFormat	   colorFormat(mapVkFormat(m_testParam.colorFormat));
578 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
579 	const bool					   normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
580 	const tcu::IVec4			   channelBitDepth		 = tcu::getTextureFormatBitDepth(colorFormat);
581 
582 	deUint32 amplifier = 1;
583 	if (normalizedColorFormat)
584 	{
585 		amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
586 						(1 << (channelBitDepth.y() - 1)) : // signed
587 						((1 << channelBitDepth.y()) - 1);  // unsigned
588 	}
589 
590 	// Samples which is not covered should be 0
591 	fragShader << "#version 450 core\n"
592 			   << "#extension GL_EXT_shader_tile_image : require\n"
593 			   << "precision highp float;\n"
594 			   << "precision highp int;\n"
595 			   << "layout( push_constant ) uniform ConstBlock\n"
596 			   << "{\n"
597 			   << "	highp uint drawIndex;\n"
598 			   << "};\n";
599 	if (!m_testParam.coherent)
600 	{
601 		fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
602 	}
603 	fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
604 			   << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
605 			   << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
606 			   << "\n"
607 			   << "void main()\n"
608 			   << "{\n"
609 			   << "	uint zero = 0;\n"
610 			   << "	uint previous = 0;\n"
611 			   << "	bool error = false;\n"
612 			   << "	for (int i = 0; i < " << sampleCount << "; ++i)\n"
613 			   << "	{\n"
614 			   << "		if (((gl_SampleMaskIn[0] >> i) & 0x1) == 0x1)\n"
615 			   << "		{\n"
616 			   << "			uvec2 previousSample = uvec2(round(colorAttachmentReadEXT"
617 			   << "(colorIn0, i) * " << amplifier << ")).xy;\n"
618 			   << "			if (previousSample.x != 0)\n"
619 			   << "			{\n"
620 			   << "				error = true;\n"
621 			   << "				break;"
622 			   << "			}\n"
623 			   << "			if (previous == 0)\n"
624 			   << "			{\n"
625 			   << "				previous = previousSample.y;\n" // write non zero value to the covered sample
626 			   << "			}\n"
627 			   << "\n"
628 			   << "			if ((patchIndex != 1 && previousSample.y == 0) || previous != previousSample.y)\n"
629 			   << "			{\n"
630 			   << "				error = true;\n"
631 			   << "				break;\n"
632 			   << "			}\n"
633 			   << "		}\n"
634 			   << "	}\n"
635 			   << "\n";
636 
637 	// add overhead after fetching data
638 	addOverhead(fragShader);
639 
640 	// write output
641 	fragShader << "if (!error && (previous + 1 == patchIndex))\n"
642 			   << "	{\n"
643 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previous + 1 + zero);\n"
644 			   << "	}\n"
645 			   << "	else\n"
646 			   << "	{\n"
647 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previous);\n"
648 			   << "		out0.x = 1;\n" // error
649 			   << "	}\n";
650 
651 	const float invAmplifier = 1.0f / static_cast<float>(amplifier);
652 	if (normalizedColorFormat)
653 	{
654 		fragShader << "		out0.y *= " << invAmplifier << ";\n";
655 	}
656 
657 	fragShader << "}\n";
658 }
659 
getDepthTestTypeFS(std::stringstream & fragShader) const660 void ShaderTileImageTestCase::getDepthTestTypeFS(std::stringstream& fragShader) const
661 {
662 	const bool		  multiSampleTest = (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
663 	const std::string depthFuncParams = multiSampleTest ? "(gl_SampleID)" : "()";
664 	const std::string colorFuncParams = multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)";
665 	const deUint32	  sampleCount	  = getSampleCount(m_testParam.m_sampleCount);
666 
667 	fragShader << "#version 450 core\n"
668 			   << "#extension GL_EXT_shader_tile_image : require\n"
669 			   << "precision highp float;\n"
670 			   << "precision highp int;\n"
671 			   << "layout( push_constant ) uniform ConstBlock\n"
672 			   << "{\n"
673 			   << "	highp uint drawIndex;\n"
674 			   << "};\n";
675 	if (!m_testParam.coherent)
676 	{
677 		fragShader << "layout( non_coherent_depth_attachment_readEXT ) in;\n";
678 		fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
679 	}
680 	fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
681 			   << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
682 			   << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
683 			   << "\n"
684 			   << "void main()\n"
685 			   << "{\n"
686 			   << "	uint zero = 0;\n"
687 			   << " uint scalingFactor = ${TOTAL_PATCH_COUNT};\n";
688 	if (multiSampleTest)
689 	{
690 		// scaling with (patch count + sample count) for multisample case
691 		fragShader << " scalingFactor += " << sampleCount << ";\n";
692 	}
693 	fragShader << "	uint previousDepth = uint(round(depthAttachmentReadEXT" << depthFuncParams
694 			   << " * scalingFactor));\n"
695 			   << "	${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT"
696 			   << colorFuncParams << "));\n";
697 
698 	// add overhead after fetching data
699 	addOverhead(fragShader);
700 
701 	// write output
702 	fragShader << "	if (previous.x == 0 && patchIndex == 1)\n"
703 			   << "	{\n"
704 			   << "		out0.y = (1u + zero + gl_SampleID);\n"
705 			   << "	}\n"
706 			   << "	else if (previous.x == 0 && (previous.y + 1) == (patchIndex + gl_SampleID) && (previousDepth + 1) "
707 				  "== (patchIndex + gl_SampleID))\n"
708 			   << "	{\n"
709 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth + 1 + zero);\n"
710 			   << "	}\n"
711 			   << "	else\n"
712 			   << "	{\n"
713 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previousDepth);\n" // debug purpose
714 			   << "		out0.x = 1;\n"									 // error
715 			   << "	}\n";
716 
717 	if (multiSampleTest)
718 	{
719 		// Depth value is written without adding SampleID.
720 		// Forcely write all fragment depth
721 		fragShader << " gl_FragDepth = float(out0.y) / scalingFactor;\n";
722 	}
723 
724 	fragShader << "}\n";
725 }
726 
getStencilTestTypeFS(std::stringstream & fragShader) const727 void ShaderTileImageTestCase::getStencilTestTypeFS(std::stringstream& fragShader) const
728 {
729 	const bool		  multiSampleTest	= (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT);
730 	const std::string stencilFuncParams = multiSampleTest ? "(gl_SampleID)" : "()";
731 	const std::string colorFuncParams	= multiSampleTest ? "(colorIn0, gl_SampleID)" : "(colorIn0)";
732 
733 	fragShader << "#version 450 core\n"
734 			   << "#extension GL_EXT_shader_tile_image : require\n"
735 			   << "precision highp float;\n"
736 			   << "precision highp int;\n"
737 			   << "layout( push_constant ) uniform ConstBlock\n"
738 			   << "{\n"
739 			   << "	highp uint drawIndex;\n"
740 			   << "};\n";
741 	if (!m_testParam.coherent)
742 	{
743 		fragShader << "layout( non_coherent_stencil_attachment_readEXT ) in;\n";
744 		fragShader << "layout( non_coherent_color_attachment_readEXT ) in;\n";
745 	}
746 	fragShader << "layout( location = 0 ) flat in uint patchIndex;\n"
747 			   << "layout( location = 0 ) tileImageEXT highp ${TILE_IMAGE_TYPE} colorIn0;\n"
748 			   << "layout( location = 0 ) out highp ${OUTPUT_VECTOR_NAME} out0;\n"
749 			   << "\n"
750 			   << "void main()\n"
751 			   << "{\n"
752 			   << "	uint zero = 0;\n"
753 			   << "	uint previousStencil = uint(round(stencilAttachmentReadEXT" << stencilFuncParams << " ));\n"
754 			   << "	${OUTPUT_VECTOR_NAME} previous = ${OUTPUT_VECTOR_NAME}(round(colorAttachmentReadEXT"
755 			   << colorFuncParams << "));\n";
756 
757 	// add overhead after fetching data
758 	addOverhead(fragShader);
759 
760 	// write output
761 	fragShader << "	if (previous.x == 0 && (previous.y + 1) == patchIndex && (previousStencil + 1) == patchIndex)\n"
762 			   << "	{\n"
763 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil + 1 + zero);\n"
764 			   << "	}\n"
765 			   << "	else\n"
766 			   << "	{\n"
767 			   << "		out0.y = ${OUTPUT_BASIC_TYPE}(previousStencil);\n" // debug purpose
768 			   << "		out0.x = 1;\n"									   // error
769 			   << "	}\n"
770 			   << "}\n";
771 }
772 
addFS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const773 void rasterization::ShaderTileImageTestCase::addFS(SourceCollections&						 programCollection,
774 												   const std::map<std::string, std::string>& params) const
775 {
776 	std::stringstream fragShader;
777 
778 	switch (m_testParam.testType)
779 	{
780 	case TestType::Color:
781 	case TestType::MultiRenderTarget:
782 	case TestType::MultiRenderTargetDynamicIndex:
783 		getColorTestTypeFS(fragShader);
784 		break;
785 	case TestType::HelperClassColor:
786 	case TestType::HelperClassDepth:
787 	case TestType::HelperClassStencil:
788 		getHelperClassTestTypeFS(fragShader);
789 		break;
790 	case TestType::MsaaSampleMask:
791 		getSampleMaskTypeFS(fragShader);
792 		break;
793 	case TestType::Depth:
794 		getDepthTestTypeFS(fragShader);
795 		break;
796 	case TestType::Stencil:
797 		getStencilTestTypeFS(fragShader);
798 		break;
799 	default:
800 		DE_ASSERT(true);
801 	}
802 
803 	tcu::StringTemplate fragShaderTpl(fragShader.str());
804 	programCollection.glslSources.add("frag") << glu::FragmentSource(fragShaderTpl.specialize(params));
805 }
806 
807 // Copy Image to Buffer using Compute Shader for handling multi sample cases
addCS(SourceCollections & programCollection,const std::map<std::string,std::string> & params) const808 void ShaderTileImageTestCase::addCS(SourceCollections&						  programCollection,
809 									const std::map<std::string, std::string>& params) const
810 {
811 	std::stringstream compShader;
812 
813 	const deUint32	  sampleCount = getSampleCount(m_testParam.m_sampleCount);
814 	const std::string fsampler	  = sampleCount > 1 ? "texture2DMS" : "texture2D";
815 	const std::string usampler	  = sampleCount > 1 ? "utexture2DMS" : "utexture2D";
816 	const std::string isampler	  = sampleCount > 1 ? "itexture2DMS" : "itexture2D";
817 
818 	const tcu::TextureFormat	   colorFormat(mapVkFormat(m_testParam.colorFormat));
819 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
820 	const tcu::IVec4			   channelBitDepth		 = tcu::getTextureFormatBitDepth(colorFormat);
821 	const bool					   normalizedColorFormat = isNormalizedColorFormat(m_testParam.colorFormat);
822 
823 	std::string sampler;
824 	switch (channelClass)
825 	{
826 	case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
827 		sampler = usampler;
828 		break;
829 	case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
830 		sampler = isampler;
831 		break;
832 	default:
833 		sampler = fsampler;
834 	}
835 
836 	deUint32 amplifier = 1;
837 
838 	if (normalizedColorFormat)
839 	{
840 		amplifier = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT) ?
841 						(1 << (channelBitDepth.y() - 1)) : // signed
842 						((1 << channelBitDepth.y()) - 1);  // unsigned
843 	}
844 
845 	// Compute shader copies color to linear layout in buffer memory
846 	compShader << "#version 450 core\n"
847 			   << "#extension GL_EXT_samplerless_texture_functions : enable\n"
848 			   << "precision highp float;\n"
849 			   << "precision highp int;\n"
850 			   << "layout(set = 0, binding = 0) uniform " << sampler << " colorTex;\n"
851 			   << "layout(set = 0, binding = 1, std430) buffer Block0 { uvec2 values[]; } colorbuf;\n"
852 			   << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
853 			   << "void main()\n"
854 			   << "{\n"
855 			   << "	for (uint i = 0u; i < " << sampleCount << "u; ++i) {\n"
856 			   << "		uint idx = ((gl_GlobalInvocationID.y * " << m_testParam.frameBufferSize
857 			   << "u) + gl_GlobalInvocationID.x) * " << sampleCount << "u + i;\n";
858 
859 	if (normalizedColorFormat)
860 	{
861 		compShader << "		colorbuf.values[idx].y = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), "
862 					  "int(i)).y * "
863 				   << amplifier << "));\n";
864 		compShader << "		colorbuf.values[idx].x = uint(round(texelFetch(colorTex, ivec2(gl_GlobalInvocationID.xy), "
865 					  "int(i)).x));\n";
866 	}
867 	else
868 	{
869 		compShader << "		colorbuf.values[idx] = uvec2(round(vec2(texelFetch(colorTex, "
870 					  "ivec2(gl_GlobalInvocationID.xy), int(i)).xy)));\n";
871 	}
872 
873 	compShader << "	}\n"
874 			   << "}\n";
875 
876 	tcu::StringTemplate computeShaderTpl(compShader.str());
877 	programCollection.glslSources.add("comp") << glu::ComputeSource(computeShaderTpl.specialize(params));
878 }
879 
initPrograms(SourceCollections & programCollection) const880 void ShaderTileImageTestCase::initPrograms(SourceCollections& programCollection) const
881 {
882 	std::map<std::string, std::string> params;
883 
884 	const deUint32				   drawCount		 = getDrawCallCount(&m_testParam);
885 	const deUint32				   patchCountPerDraw = getPatchesPerDrawCount(m_testParam.multiplePatchesPerDraw);
886 	const deUint32				   attachmentCount	 = getColorAttachmentCount(m_testParam.testType);
887 	const tcu::TextureFormat	   colorFormat(mapVkFormat(m_testParam.colorFormat));
888 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
889 
890 	params["VERTEX_COUNT_PER_PATCH"] = std::to_string(getVertexCountPerPatch(&m_testParam));
891 	params["PATCH_COUNT_PER_DRAW"]	 = std::to_string(patchCountPerDraw);
892 	params["INV_TOTAL_PATCH_COUNT"]	 = std::to_string(1.0f / static_cast<float>(drawCount * patchCountPerDraw));
893 	params["TOTAL_PATCH_COUNT"]		 = std::to_string(drawCount * patchCountPerDraw);
894 	params["ATTACHMENT_COUNT"]		 = std::to_string(attachmentCount);
895 
896 	std::string strVecName;
897 	std::string strBasicType;
898 	std::string strTileImageType;
899 
900 	switch (channelClass)
901 	{
902 	case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
903 		strVecName		 = "uvec";
904 		strTileImageType = "uattachmentEXT";
905 		strBasicType	 = "uint";
906 		break;
907 	case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
908 		strVecName		 = "ivec";
909 		strTileImageType = "iattachmentEXT";
910 		strBasicType	 = "int";
911 		break;
912 	default:
913 		strVecName		 = "vec";
914 		strTileImageType = "attachmentEXT";
915 		strBasicType	 = "float";
916 	}
917 	params["OUTPUT_VECTOR_NAME"] = strVecName + std::to_string(tcu::getNumUsedChannels(colorFormat.order));
918 	params["OUTPUT_BASIC_TYPE"]	 = strBasicType;
919 	params["TILE_IMAGE_TYPE"]	 = strTileImageType;
920 
921 	addVS(programCollection, params);
922 	addFS(programCollection, params);
923 	addCS(programCollection, params);
924 }
925 
createInstance(Context & context) const926 TestInstance* ShaderTileImageTestCase::createInstance(Context& context) const
927 {
928 	return new ShaderTileImageTestInstance(context, &m_testParam);
929 }
930 
checkSupport(Context & context) const931 void ShaderTileImageTestCase::checkSupport(Context& context) const
932 {
933 	if (!context.requireDeviceFunctionality("VK_KHR_dynamic_rendering"))
934 	{
935 		TCU_THROW(NotSupportedError, "VK_KHR_dynamic_rendering not supported");
936 	}
937 
938 	if (!context.requireDeviceFunctionality("VK_EXT_shader_tile_image"))
939 	{
940 		TCU_THROW(NotSupportedError, "VK_EXT_shader_tile_image not supported");
941 	}
942 	/* sampleRateShading must be enabled to call fragment shader for all the samples in multisampling */
943 	VkPhysicalDeviceShaderTileImageFeaturesEXT shaderTileImageFeature = {};
944 	shaderTileImageFeature.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_FEATURES_EXT;
945 
946 	VkPhysicalDeviceFeatures  features	= {};
947 	VkPhysicalDeviceFeatures2 features2 = {};
948 	features2.sType						= VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
949 	features2.pNext						= &shaderTileImageFeature;
950 
951 	context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features);
952 	context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
953 
954 	if (!shaderTileImageFeature.shaderTileImageColorReadAccess)
955 	{
956 		TCU_THROW(NotSupportedError, "color read access of VK_EXT_shader_tile_image is not supported");
957 	}
958 	switch (m_testParam.testType)
959 	{
960 	case TestType::Depth:
961 	case TestType::HelperClassDepth:
962 		if (!shaderTileImageFeature.shaderTileImageDepthReadAccess)
963 		{
964 			TCU_THROW(NotSupportedError, "depth read access of VK_EXT_shader_tile_image is not supported");
965 		}
966 		break;
967 	case TestType::Stencil:
968 	case TestType::HelperClassStencil:
969 		if (!shaderTileImageFeature.shaderTileImageStencilReadAccess)
970 		{
971 			TCU_THROW(NotSupportedError, "stencil read access of VK_EXT_shader_tile_image is not supported");
972 		}
973 		break;
974 	case TestType::Color:
975 	case TestType::MultiRenderTarget:
976 	case TestType::MultiRenderTargetDynamicIndex:
977 	case TestType::MsaaSampleMask:
978 	case TestType::HelperClassColor:
979 		break;
980 	default:
981 		DE_ASSERT(0);
982 	}
983 
984 	VkPhysicalDeviceVulkan12Properties vulkan12Properties = {};
985 	vulkan12Properties.sType							  = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_PROPERTIES;
986 
987 	VkPhysicalDeviceShaderTileImagePropertiesEXT shaderTileImageProperties = {};
988 	shaderTileImageProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_TILE_IMAGE_PROPERTIES_EXT;
989 	shaderTileImageProperties.pNext = &vulkan12Properties;
990 
991 	VkPhysicalDeviceProperties2 properties = {};
992 	properties.sType					   = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
993 	properties.pNext					   = &shaderTileImageProperties;
994 
995 	context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties);
996 
997 	// shaderTileImageReadSampleFromPixelRateInvocation is a boolean that will be VK_TRUE if reading from samples from a
998 	// pixel rate fragment invocation is supported when VkPipelineMultisampleStateCreateInfo::rasterizationSamples > 1.
999 	// shaderTileImageReadFromHelperInvocation is a boolean that will be VK_TRUE if reads of tile image data from helper
1000 	// fragment invocations result in valid values.
1001 	if (!shaderTileImageProperties.shaderTileImageReadSampleFromPixelRateInvocation)
1002 	{
1003 		if (m_testParam.testType == TestType::MsaaSampleMask)
1004 		{
1005 			TCU_THROW(NotSupportedError, "multi-samples pixel access of VK_EXT_shader_tile_image is not supported");
1006 		}
1007 	}
1008 
1009 	if (!shaderTileImageProperties.shaderTileImageReadFromHelperInvocation)
1010 	{
1011 		if (isHelperClassTest(m_testParam.testType))
1012 		{
1013 			TCU_THROW(NotSupportedError, "helper class fragments access of VK_EXT_shader_tile_image is not supported");
1014 		}
1015 	}
1016 
1017 	const tcu::TextureFormat	   colorFormat(mapVkFormat(m_testParam.colorFormat));
1018 	const tcu::TextureChannelClass channelClass(tcu::getTextureChannelClass(colorFormat.type));
1019 	if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER ||
1020 		channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1021 	{
1022 		if ((vulkan12Properties.framebufferIntegerColorSampleCounts & m_testParam.m_sampleCount) == 0 ||
1023 			(properties.properties.limits.sampledImageIntegerSampleCounts & m_testParam.m_sampleCount) == 0)
1024 		{
1025 			TCU_THROW(NotSupportedError, "Sample count not supported");
1026 		}
1027 	}
1028 	else
1029 	{
1030 		if ((properties.properties.limits.framebufferColorSampleCounts & m_testParam.m_sampleCount) == 0 ||
1031 			(properties.properties.limits.sampledImageColorSampleCounts & m_testParam.m_sampleCount) == 0)
1032 		{
1033 			TCU_THROW(NotSupportedError, "Sample count not supported");
1034 		}
1035 	}
1036 
1037 	if (m_testParam.m_sampleCount != VK_SAMPLE_COUNT_1_BIT && m_testParam.testType != TestType::MsaaSampleMask &&
1038 		!features.sampleRateShading)
1039 	{
1040 		TCU_THROW(NotSupportedError, "sampleRateShading feature not supported");
1041 	}
1042 
1043 	const deUint32 attachmentCount = getColorAttachmentCount(m_testParam.testType);
1044 
1045 	if (properties.properties.limits.maxFragmentOutputAttachments < attachmentCount ||
1046 		properties.properties.limits.maxPerStageDescriptorInputAttachments < attachmentCount)
1047 	{
1048 		TCU_THROW(NotSupportedError, "attachment number not supported");
1049 	}
1050 
1051 	const InstanceInterface& vki			= context.getInstanceInterface();
1052 	VkPhysicalDevice		 physicalDevice = context.getPhysicalDevice();
1053 	const VkFormatProperties colorFormatProperties(
1054 		getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.colorFormat));
1055 	const VkFormatProperties dsFormatProperties(
1056 		getPhysicalDeviceFormatProperties(vki, physicalDevice, m_testParam.depthStencilFormat));
1057 
1058 	if ((colorFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) == 0)
1059 	{
1060 		TCU_THROW(NotSupportedError, "Format can't be used as color attachment");
1061 	}
1062 
1063 	if ((dsFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) == 0)
1064 	{
1065 		TCU_THROW(NotSupportedError, "Format can't be used as depth stencil attachment");
1066 	}
1067 }
1068 
ShaderTileImageTestInstance(Context & context,const TestParam * testParam)1069 ShaderTileImageTestInstance::ShaderTileImageTestInstance(Context& context, const TestParam* testParam)
1070 	: TestInstance(context), m_testParam(testParam), m_vk(m_context.getDeviceInterface())
1071 {
1072 	initialize();
1073 }
1074 
initialize()1075 void ShaderTileImageTestInstance::initialize()
1076 {
1077 	generateCmdBuffer();
1078 	generateAttachments();
1079 	generateVertexBuffer();
1080 	m_graphicsPipeline				 = generateGraphicsPipeline(false, false, false);
1081 	m_graphicsPipelineForHelperClass = generateGraphicsPipeline(true, true, true);
1082 	generateComputePipeline();
1083 }
1084 
generateComputePipeline()1085 void ShaderTileImageTestInstance::generateComputePipeline()
1086 {
1087 	const deUint32 attachmentSize = getColorAttachmentCount(m_testParam->testType);
1088 	const VkDevice device		  = m_context.getDevice();
1089 
1090 	const Unique<VkShaderModule> cs(createShaderModule(m_vk, device, m_context.getBinaryCollection().get("comp"), 0));
1091 
1092 	VkDescriptorSetLayoutCreateFlags layoutCreateFlags = 0;
1093 
1094 	const VkDescriptorSetLayoutBinding bindings[] = {
1095 		{
1096 			0,								  // binding
1097 			VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, // descriptorType
1098 			1,								  // descriptorCount
1099 			VK_SHADER_STAGE_COMPUTE_BIT,	  // stageFlags
1100 			DE_NULL,						  // pImmutableSamplers
1101 		},
1102 		{
1103 			1,								   // binding
1104 			VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // descriptorType
1105 			1,								   // descriptorCount
1106 			VK_SHADER_STAGE_COMPUTE_BIT,	   // stageFlags
1107 			DE_NULL,						   // pImmutableSamplers
1108 		},
1109 	};
1110 
1111 	// Create a layout and allocate a descriptor set for it.
1112 	const VkDescriptorSetLayoutCreateInfo setLayoutCreateInfo = {
1113 		vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // sType
1114 		DE_NULL,												 // pNext
1115 		layoutCreateFlags,										 // flags
1116 		sizeof(bindings) / sizeof(bindings[0]),					 // bindingCount
1117 		&bindings[0]											 // pBindings
1118 	};
1119 
1120 	m_computeDescriptorSetLayout = vk::createDescriptorSetLayout(m_vk, device, &setLayoutCreateInfo);
1121 
1122 	const VkPipelineShaderStageCreateInfo csShaderCreateInfo = {
1123 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1124 		DE_NULL,
1125 		(VkPipelineShaderStageCreateFlags)0,
1126 		VK_SHADER_STAGE_COMPUTE_BIT, // stage
1127 		*cs,						 // shader
1128 		"main",
1129 		DE_NULL, // pSpecializationInfo
1130 	};
1131 
1132 	const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
1133 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // sType
1134 		DE_NULL,									   // pNext
1135 		(VkPipelineLayoutCreateFlags)0,
1136 		1,									 // setLayoutCount
1137 		&m_computeDescriptorSetLayout.get(), // pSetLayouts
1138 		0,									 // pushConstantRangeCount
1139 		DE_NULL,							 // pPushConstantRanges
1140 	};
1141 
1142 	m_computePipelineLayout = createPipelineLayout(m_vk, device, &pipelineLayoutCreateInfo, NULL);
1143 
1144 	const VkComputePipelineCreateInfo pipelineCreateInfo = {
1145 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1146 		DE_NULL,
1147 		0u,						  // flags
1148 		csShaderCreateInfo,		  // cs
1149 		*m_computePipelineLayout, // layout
1150 		(vk::VkPipeline)0,		  // basePipelineHandle
1151 		0u,						  // basePipelineIndex
1152 	};
1153 
1154 	m_computePipeline = createComputePipeline(m_vk, device, DE_NULL, &pipelineCreateInfo, NULL);
1155 
1156 	VkDescriptorPoolCreateFlags poolCreateFlags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
1157 
1158 	vk::DescriptorPoolBuilder poolBuilder;
1159 	for (deUint32 i = 0; i < (deInt32)(sizeof(bindings) / sizeof(bindings[0])); ++i)
1160 	{
1161 		poolBuilder.addType(bindings[i].descriptorType, bindings[i].descriptorCount * attachmentSize);
1162 	}
1163 	m_descriptorPool = poolBuilder.build(m_vk, device, poolCreateFlags, attachmentSize);
1164 
1165 	for (deUint32 i = 0; i < attachmentSize; ++i)
1166 	{
1167 		m_descriptorSets[i] = makeDescriptorSet(m_vk, device, *m_descriptorPool, *m_computeDescriptorSetLayout);
1168 		VkDescriptorImageInfo  imageInfo;
1169 		VkDescriptorBufferInfo bufferInfo;
1170 
1171 		VkWriteDescriptorSet w = {
1172 			VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
1173 			DE_NULL,								// pNext
1174 			*m_descriptorSets[i],					// dstSet
1175 			(deUint32)0,							// dstBinding
1176 			0,										// dstArrayElement
1177 			1u,										// descriptorCount
1178 			bindings[0].descriptorType,				// descriptorType
1179 			&imageInfo,								// pImageInfo
1180 			&bufferInfo,							// pBufferInfo
1181 			DE_NULL,								// pTexelBufferView
1182 		};
1183 
1184 		imageInfo = makeDescriptorImageInfo(DE_NULL, *m_imageColorView[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1185 		w.dstBinding	 = 0;
1186 		w.descriptorType = bindings[0].descriptorType;
1187 		m_vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1188 
1189 		bufferInfo		 = makeDescriptorBufferInfo(m_imageBuffer[i]->object(), 0, VK_WHOLE_SIZE);
1190 		w.dstBinding	 = 1;
1191 		w.descriptorType = bindings[1].descriptorType;
1192 		m_vk.updateDescriptorSets(device, 1, &w, 0, NULL);
1193 	}
1194 }
1195 
generateGraphicsPipeline(bool disableColor0Write,bool disableDepthWrite,bool disableStencilWrite)1196 Move<VkPipeline> ShaderTileImageTestInstance::generateGraphicsPipeline(bool disableColor0Write, bool disableDepthWrite,
1197 																	   bool disableStencilWrite)
1198 {
1199 	const VkDevice device = m_context.getDevice();
1200 
1201 	VkPushConstantRange pushConstant;
1202 	pushConstant.offset		= 0;
1203 	pushConstant.size		= sizeof(deUint32);
1204 	pushConstant.stageFlags = (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT);
1205 
1206 	m_graphicsPipelineLayout = makePipelineLayout(m_vk, device, 0, nullptr, 1, &pushConstant);
1207 	m_vertexModule			 = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("vert"), 0u);
1208 	m_fragmentModule		 = createShaderModule(m_vk, device, m_context.getBinaryCollection().get("frag"), 0u);
1209 
1210 	const VkVertexInputBindingDescription vertexInputBindingDescription = {
1211 		0,							 // deUint32 binding;
1212 		sizeof(tcu::Vec2),			 // deUint32 strideInBytes;
1213 		VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputStepRate stepRate;
1214 	};
1215 
1216 	const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
1217 		0u,						 // deUint32 location;
1218 		0u,						 // deUint32 binding;
1219 		VK_FORMAT_R32G32_SFLOAT, // VkFormat format;
1220 		0u,						 // deUint32 offsetInBytes;
1221 	};
1222 
1223 	const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1224 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1225 		DE_NULL,												   // const void* pNext;
1226 		0,														   // VkPipelineVertexInputStateCreateFlags	flags;
1227 		1u,														   // deUint32 bindingCount;
1228 		&vertexInputBindingDescription,	  // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1229 		1u,								  // deUint32 attributeCount;
1230 		&vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1231 	};
1232 
1233 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = {
1234 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1235 		DE_NULL,													 // const void* pNext;
1236 		(VkPipelineInputAssemblyStateCreateFlags)0,					 // VkPipelineInputAssemblyStateCreateFlags flags;
1237 		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,						 // VkPrimitiveTopology topology;
1238 		VK_FALSE,													 // VkBool32 primitiveRestartEnable;
1239 	};
1240 
1241 	const VkViewport viewport{
1242 		0, 0, static_cast<float>(m_testParam->frameBufferSize), static_cast<float>(m_testParam->frameBufferSize), 0, 1
1243 	};
1244 	const VkRect2D scissor{ { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } };
1245 
1246 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = {
1247 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1248 		DE_NULL,											   // const void* pNext;
1249 		(VkPipelineViewportStateCreateFlags)0,				   // VkPipelineViewportStateCreateFlags flags;
1250 		1u,													   // uint32_t viewportCount;
1251 		&viewport,											   // const VkViewport* pViewports;
1252 		1u,													   // uint32_t scissorCount;
1253 		&scissor,											   // const VkRect2D* pScissors;
1254 	};
1255 
1256 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = {
1257 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1258 		DE_NULL,													// const void* pNext;
1259 		0u,															// VkPipelineRasterizationStateCreateFlags flags;
1260 		VK_FALSE,													// VkBool32 depthClampEnable;
1261 		VK_FALSE,													// VkBool32 rasterizerDiscardEnable;
1262 		VK_POLYGON_MODE_FILL,										// VkPolygonMode polygonMode;
1263 		VK_CULL_MODE_NONE,											// VkCullModeFlags cullMode;
1264 		VK_FRONT_FACE_COUNTER_CLOCKWISE,							// VkFrontFace frontFace;
1265 		VK_FALSE,													// VkBool32 depthBiasEnable;
1266 		0.0f,														// float depthBiasConstantFactor;
1267 		0.0f,														// float depthBiasClamp;
1268 		0.0f,														// float depthBiasSlopeFactor;
1269 		1.0f,														// float lineWidth;
1270 	};
1271 
1272 	const VkSampleMask	sampleMask	= getSampleMask(m_testParam->testType);
1273 	const VkSampleMask* pSampleMask = (m_testParam->testType == TestType::MsaaSampleMask) ? &sampleMask : DE_NULL;
1274 	const bool			sampleShadingEnable = (m_testParam->testType != TestType::MsaaSampleMask);
1275 
1276 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = {
1277 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1278 		DE_NULL,												  // const void* pNext;
1279 		0u,														  // VkPipelineMultisampleStateCreateFlags flags;
1280 		m_testParam->m_sampleCount,								  // VkSampleCountFlagBits rasterizationSamples;
1281 		sampleShadingEnable,									  // VkBool32 sampleShadingEnable;
1282 		1.0f,													  // float minSampleShading;
1283 		pSampleMask,											  // const VkSampleMask* pSampleMask;
1284 		VK_FALSE,												  // VkBool32 alphaToCoverageEnable;
1285 		VK_FALSE												  // VkBool32 alphaToOneEnable;
1286 	};
1287 
1288 	std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1289 		getColorAttachmentCount(m_testParam->testType),
1290 		{
1291 			false,												  // VkBool32 blendEnable;
1292 			VK_BLEND_FACTOR_ONE,								  // VkBlend srcBlendColor;
1293 			VK_BLEND_FACTOR_ONE,								  // VkBlend destBlendColor;
1294 			VK_BLEND_OP_ADD,									  // VkBlendOp blendOpColor;
1295 			VK_BLEND_FACTOR_ONE,								  // VkBlend srcBlendAlpha;
1296 			VK_BLEND_FACTOR_ONE,								  // VkBlend destBlendAlpha;
1297 			VK_BLEND_OP_ADD,									  // VkBlendOp blendOpAlpha;
1298 			(VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT) // VkChannelFlags channelWriteMask;
1299 		});
1300 
1301 	if (disableColor0Write)
1302 	{
1303 		colorBlendAttachmentState[0].colorWriteMask = 0;
1304 	}
1305 
1306 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = {
1307 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1308 		DE_NULL,												  // const void* pNext;
1309 		/* always needed */
1310 		0,											// VkPipelineColorBlendStateCreateFlags flags;
1311 		false,										// VkBool32 logicOpEnable;
1312 		VK_LOGIC_OP_COPY,							// VkLogicOp logicOp;
1313 		(deUint32)colorBlendAttachmentState.size(), // deUint32 attachmentCount;
1314 		colorBlendAttachmentState.data(),			// const VkPipelineColorBlendAttachmentState* pAttachments;
1315 		{ 0.0f, 0.0f, 0.0f, 0.0f },					// float blendConst[4];
1316 	};
1317 
1318 	VkStencilOpState stencilOpState = {
1319 		VK_STENCIL_OP_ZERO,				  // VkStencilOp failOp;
1320 		VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp passOp;
1321 		VK_STENCIL_OP_INCREMENT_AND_WRAP, // VkStencilOp depthFailOp;
1322 		VK_COMPARE_OP_ALWAYS,			  // VkCompareOp compareOp;
1323 		0xff,							  // uint32_t compareMask;
1324 		0xff,							  // uint32_t writeMask;
1325 		0,								  // uint32_t reference;
1326 	};
1327 
1328 	if (disableStencilWrite)
1329 	{
1330 		stencilOpState.failOp	   = VK_STENCIL_OP_KEEP;
1331 		stencilOpState.passOp	   = VK_STENCIL_OP_KEEP;
1332 		stencilOpState.depthFailOp = VK_STENCIL_OP_KEEP;
1333 	}
1334 
1335 	VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = {
1336 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1337 		// VkStructureType sType;
1338 		DE_NULL, // const void* pNext;
1339 		0,
1340 		// VkPipelineDepthStencilStateCreateFlags flags;
1341 		VK_TRUE,			  // VkBool32 depthTestEnable;
1342 		VK_TRUE,			  // VkBool32 depthWriteEnable;
1343 		VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp;
1344 		VK_FALSE,			  // VkBool32 depthBoundsTestEnable;
1345 		VK_TRUE,			  // VkBool32 stencilTestEnable;
1346 		stencilOpState,		  // VkStencilOpState front;
1347 		stencilOpState,		  // VkStencilOpState back;
1348 		0.0f,				  // float minDepthBounds;
1349 		1.0f,				  // float maxDepthBounds;
1350 	};
1351 
1352 	if (disableDepthWrite)
1353 	{
1354 		pipelineDepthStencilStateInfo.depthWriteEnable = VK_FALSE;
1355 	}
1356 
1357 	std::vector<VkFormat>				   colorsAttachmentFormats(getColorAttachmentCount(m_testParam->testType),
1358 																   m_testParam->colorFormat);
1359 	const tcu::TextureFormat depthStencilTexFormat = mapVkFormat(m_testParam->depthStencilFormat);
1360 	VkFormat depthFormat = tcu::hasDepthComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED;
1361 	VkFormat stencilFormat = tcu::hasStencilComponent(depthStencilTexFormat.order) ? m_testParam->depthStencilFormat : VK_FORMAT_UNDEFINED;
1362 	const VkPipelineRenderingCreateInfoKHR renderingCreateInfo{
1363 		VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,	// VkStructureType sType;
1364 		DE_NULL,												// const void* pNext;
1365 		0u,														// deUint32 viewMask;
1366 		static_cast<deUint32>(colorsAttachmentFormats.size()),	// deUint32 colorAttachmentCount;
1367 		colorsAttachmentFormats.data(),							// const VkFormat* pColorAttachmentFormats;
1368 		depthFormat,											// VkFormat depthAttachmentFormat;
1369 		stencilFormat,											// VkFormat stencilAttachmentFormat;
1370 	};
1371 
1372 	const VkPipelineShaderStageCreateInfo pShaderStages[] = {
1373 		{
1374 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1375 			DE_NULL,											 // const void*	 pNext;
1376 			(VkPipelineShaderStageCreateFlags)0,				 // VkPipelineShaderStageCreateFlags flags;
1377 			VK_SHADER_STAGE_VERTEX_BIT,							 // VkShaderStageFlagBits stage;
1378 			*m_vertexModule,									 // VkShaderModule module;
1379 			"main",												 // const char* pName;
1380 			DE_NULL,											 // const VkSpecializationInfo* pSpecializationInfo;
1381 		},
1382 		{
1383 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1384 			DE_NULL,											 // const void* pNext;
1385 			(VkPipelineShaderStageCreateFlags)0,				 // VkPipelineShaderStageCreateFlags flags;
1386 			VK_SHADER_STAGE_FRAGMENT_BIT,						 // VkShaderStageFlagBits stage;
1387 			*m_fragmentModule,									 // VkShaderModule module;
1388 			"main",												 // const char* pName;
1389 			DE_NULL,											 // const VkSpecializationInfo* pSpecializationInfo;
1390 		},
1391 	};
1392 
1393 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = {
1394 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1395 		&renderingCreateInfo,							 // const void* pNext;
1396 		(VkPipelineCreateFlags)0,						 // VkPipelineCreateFlags flags;
1397 		2u,												 // deUint32 stageCount;
1398 		pShaderStages,									 // const VkPipelineShaderStageCreateInfo* pStages;
1399 		&vertexInputStateParams,		 // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1400 		&pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1401 		DE_NULL,						 // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1402 		&pipelineViewportStateInfo,		 // const VkPipelineViewportStateCreateInfo* pViewportState;
1403 		&pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1404 		&pipelineMultisampleStateInfo,	 // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1405 		&pipelineDepthStencilStateInfo,	 // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1406 		&pipelineColorBlendStateInfo,	 // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1407 		DE_NULL,						 // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1408 		*m_graphicsPipelineLayout,		 // VkPipelineLayout layout;
1409 		DE_NULL,						 // VkRenderPass renderPass;
1410 		0u,								 // deUint32 subpass;
1411 		DE_NULL,						 // VkPipeline basePipelineHandle;
1412 		0,								 // deInt32 basePipelineIndex;
1413 	};
1414 
1415 	return createGraphicsPipeline(m_vk, device, DE_NULL, &graphicsPipelineInfo);
1416 }
1417 
generateAttachments()1418 void ShaderTileImageTestInstance::generateAttachments()
1419 {
1420 	const VkDevice device	 = m_context.getDevice();
1421 	Allocator&	   allocator = m_context.getDefaultAllocator();
1422 
1423 	auto makeImageCreateInfo = [](const VkFormat format, deUint32 imageSize, VkSampleCountFlagBits sampleCount,
1424 								  VkImageUsageFlags usage) -> VkImageCreateInfo
1425 	{
1426 		const VkImageCreateInfo imageParams = {
1427 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,   // VkStructureType sType;
1428 			DE_NULL,							   // const void* pNext;
1429 			(VkImageCreateFlags)0,				   // VkImageCreateFlags flags;
1430 			VK_IMAGE_TYPE_2D,					   // VkImageType imageType;
1431 			format,								   // VkFormat format;
1432 			makeExtent3D(imageSize, imageSize, 1), // VkExtent3D extent;
1433 			1u,									   // deUint32 mipLevels;
1434 			1u,									   // deUint32 arrayLayers;
1435 			sampleCount,						   // VkSampleCountFlagBits	samples;
1436 			VK_IMAGE_TILING_OPTIMAL,			   // VkImageTiling tiling;
1437 			usage,								   // VkImageUsageFlags usage;
1438 			VK_SHARING_MODE_EXCLUSIVE,			   // VkSharingMode sharingMode;
1439 			0u,									   // deUint32 queueFamilyIndexCount;
1440 			DE_NULL,							   // const deUint32* pQueueFamilyIndices;
1441 			VK_IMAGE_LAYOUT_UNDEFINED,			   // VkImageLayout initialLayout;
1442 		};
1443 		return imageParams;
1444 	};
1445 
1446 	// Color Attachment
1447 	{
1448 		constexpr deUint32		imageBufferPixelSize = sizeof(deUint32) * 2; // always uvec2 type
1449 		const VkImageUsageFlags imageUsage =
1450 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1451 		const VkDeviceSize imageBufferSize = m_testParam->frameBufferSize * m_testParam->frameBufferSize *
1452 											 imageBufferPixelSize * getSampleCount(m_testParam->m_sampleCount);
1453 		const VkImageSubresourceRange imageSubresource =
1454 			makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1455 		const VkImageCreateInfo	 imageInfo = makeImageCreateInfo(m_testParam->colorFormat, m_testParam->frameBufferSize,
1456 																 m_testParam->m_sampleCount, imageUsage);
1457 		const VkBufferCreateInfo bufferInfo = makeBufferCreateInfo(
1458 			imageBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
1459 
1460 		const deUint32 attachmentCount = getColorAttachmentCount(m_testParam->testType);
1461 		for (deUint32 i = 0; i < attachmentCount; ++i)
1462 		{
1463 			m_imageColor[i]		 = makeImage(m_vk, device, imageInfo);
1464 			m_imageColorAlloc[i] = bindImage(m_vk, device, allocator, *m_imageColor[i], MemoryRequirement::Any);
1465 			m_imageBuffer[i] =
1466 				Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible);
1467 			m_imageColorView[i] = makeImageView(m_vk, device, *m_imageColor[i], VK_IMAGE_VIEW_TYPE_2D,
1468 												m_testParam->colorFormat, imageSubresource);
1469 		}
1470 
1471 		m_imageColorBufferHostPtr = static_cast<deUint32*>(m_imageBuffer[0]->getHostPtr());
1472 	}
1473 
1474 	// depth/stencil attachment.
1475 	{
1476 		const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat);
1477 		const VkImageUsageFlags	 imageUsage =
1478 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
1479 
1480 		VkImageAspectFlags aspect = 0;
1481 		if (tcu::hasDepthComponent(depthStencilFormat.order))
1482 		{
1483 			aspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
1484 		}
1485 		if (tcu::hasStencilComponent(depthStencilFormat.order))
1486 		{
1487 			aspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
1488 		}
1489 
1490 		const VkImageCreateInfo imageInfo = makeImageCreateInfo(
1491 			m_testParam->depthStencilFormat, m_testParam->frameBufferSize, m_testParam->m_sampleCount, imageUsage);
1492 
1493 		const VkImageSubresourceRange imageSubresource = makeImageSubresourceRange(aspect, 0u, 1u, 0u, 1u);
1494 
1495 		m_imageDepthStencil		 = makeImage(m_vk, device, imageInfo);
1496 		m_imageDepthStencilAlloc = bindImage(m_vk, device, allocator, *m_imageDepthStencil, MemoryRequirement::Any);
1497 		m_imageDepthStencilView	 = makeImageView(m_vk, device, *m_imageDepthStencil, VK_IMAGE_VIEW_TYPE_2D,
1498 												 m_testParam->depthStencilFormat, imageSubresource);
1499 	}
1500 }
1501 
generateVertexBuffer()1502 void ShaderTileImageTestInstance::generateVertexBuffer()
1503 {
1504 	const deUint32		   drawCount		 = getDrawCallCount(m_testParam);
1505 	const deUint32		   patchCountPerDraw = getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1506 	const deUint32		   queueFamilyIndex	 = m_context.getUniversalQueueFamilyIndex();
1507 	const VkDevice		   device			 = m_context.getDevice();
1508 	Allocator&			   allocator		 = m_context.getDefaultAllocator();
1509 	std::vector<tcu::Vec2> vbo;
1510 	for (deUint32 patchIndex = 0; patchIndex < (patchCountPerDraw * drawCount); patchIndex++)
1511 	{
1512 		// _____
1513 		// |  /
1514 		// | /
1515 		// |/
1516 		vbo.emplace_back(tcu::Vec2(-1, -1));
1517 		vbo.emplace_back(tcu::Vec2(1, 1));
1518 		vbo.emplace_back(tcu::Vec2(-1, 1));
1519 
1520 		if (getVertexCountPerPatch(m_testParam) == 6)
1521 		{
1522 			if (isHelperClassTest(m_testParam->testType) && patchIndex == 0)
1523 			{
1524 				// helper class cases render the first patch like follow.
1525 				// _____
1526 				// |  /
1527 				// | /
1528 				// |/
1529 				// So, 3 of second triangle is dummy.
1530 				vbo.emplace_back(tcu::Vec2(-1, -1));
1531 				vbo.emplace_back(tcu::Vec2(-1, -1));
1532 				vbo.emplace_back(tcu::Vec2(-1, -1));
1533 			}
1534 			else
1535 			{
1536 				// Other 6 vertices cases render like follow
1537 				// _____
1538 				// |  /|
1539 				// | / |
1540 				// |/__|
1541 				vbo.emplace_back(tcu::Vec2(-1, -1));
1542 				vbo.emplace_back(tcu::Vec2(1, -1));
1543 				vbo.emplace_back(tcu::Vec2(1, 1));
1544 			}
1545 		}
1546 	}
1547 
1548 	const size_t dataSize = vbo.size() * sizeof(tcu::Vec2);
1549 	{
1550 		const VkBufferCreateInfo bufferInfo = {
1551 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1552 			DE_NULL,							  // const void* pNext;
1553 			0u,									  // VkBufferCreateFlags flags;
1554 			dataSize,							  // VkDeviceSize size;
1555 			VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,	  // VkBufferUsageFlags	usage;
1556 			VK_SHARING_MODE_EXCLUSIVE,			  // VkSharingMode sharingMode;
1557 			1u,									  // deUint32 queueFamilyCount;
1558 			&queueFamilyIndex					  // const deUint32* pQueueFamilyIndices;
1559 		};
1560 		m_vertexBuffer =
1561 			Draw::Buffer::createAndAlloc(m_vk, device, bufferInfo, allocator, MemoryRequirement::HostVisible);
1562 	}
1563 
1564 	/* Load vertices into vertex buffer */
1565 	deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), vbo.data(), dataSize);
1566 	flushAlloc(m_vk, device, m_vertexBuffer->getBoundMemory());
1567 }
generateCmdBuffer()1568 void ShaderTileImageTestInstance::generateCmdBuffer()
1569 {
1570 	const VkDevice device = m_context.getDevice();
1571 
1572 	m_cmdPool	= createCommandPool(m_vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
1573 									m_context.getUniversalQueueFamilyIndex());
1574 	m_cmdBuffer = allocateCommandBuffer(m_vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1575 }
1576 
iterate()1577 tcu::TestStatus ShaderTileImageTestInstance::iterate()
1578 {
1579 	rendering();
1580 	return checkResult();
1581 }
1582 
getResultValue(deUint32 fx,deUint32 fy,deUint32 fs,deUint32 renderTargetID) const1583 deUint32 ShaderTileImageTestInstance::getResultValue(deUint32 fx, deUint32 fy, deUint32 fs,
1584 													 deUint32 renderTargetID) const
1585 {
1586 	const deUint32* resultData =
1587 		static_cast<const deUint32*>(m_imageBuffer[renderTargetID]->getBoundMemory().getHostPtr());
1588 	const deUint32 sampleCount = getSampleCount(m_testParam->m_sampleCount);
1589 	const deUint32 index	   = (((fy * m_testParam->frameBufferSize) + fx) * sampleCount + fs) * 2; // 2 is for xy
1590 	if (resultData[index] != 0)																		  // error
1591 	{
1592 		return 0xFFFFFFFF;
1593 	}
1594 
1595 	return resultData[index + 1]; // y value
1596 }
1597 
simulate(deUint32 fx,deUint32 fy,deUint32 fs,deUint32 renderTargetID) const1598 deUint32 ShaderTileImageTestInstance::simulate(deUint32 fx, deUint32 fy, deUint32 fs, deUint32 renderTargetID) const
1599 {
1600 	const deUint32 totalLayerCount =
1601 		getDrawCallCount(m_testParam) * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1602 
1603 	if (m_testParam->testType == TestType::MsaaSampleMask)
1604 	{
1605 		deUint32 expectedValue = 0;
1606 
1607 		if (((getSampleMask(m_testParam->testType) >> fs) & 0x1) == 0x1)
1608 		{
1609 			expectedValue = totalLayerCount + renderTargetID;
1610 		}
1611 		return expectedValue;
1612 	}
1613 	if (m_testParam->testType == TestType::Stencil)
1614 	{
1615 		// stencil test doesn't add fragment sample ID to the output;
1616 		const deUint32 expectedValue = totalLayerCount + renderTargetID;
1617 		return expectedValue;
1618 	}
1619 	if (isHelperClassTest(m_testParam->testType))
1620 	{
1621 		// ________      ________      ________
1622 		// 1|1|1|0|      0|0|*|1|      1|1|#|2|
1623 		// 1|1|0|0|      0|0|1|*|      1|1|2|#|
1624 		// 1|0|0|0|  =>  *|1|0|0|  =>  #|2|1|1|
1625 		// 0|0|0|0|      1|*|0|0|      2|#|1|1|
1626 		// ________      ________      ________
1627 		// raster       max(dx,dy)    result(+1)
1628 		// *(#): max(dx, dy) could be 0(1) or 1(2).
1629 		if ((fx) == (fy))
1630 		{
1631 			return kDerivative1; // derivative is 1 because of coverage. (+1) for differentiate clear value
1632 		}
1633 		else
1634 		{
1635 			return kDerivative0; // 0, fill all or fill none for quad. (+1) for differentiate clear value
1636 		}
1637 	}
1638 	else
1639 	{
1640 		const deUint32 expectedValue = totalLayerCount + renderTargetID + fs;
1641 		return expectedValue;
1642 	}
1643 }
1644 
checkResult() const1645 tcu::TestStatus ShaderTileImageTestInstance::checkResult() const
1646 {
1647 	const VkDevice device = m_context.getDevice();
1648 
1649 	qpTestResult   res				   = QP_TEST_RESULT_PASS;
1650 	const deUint32 sampleCount		   = getSampleCount(m_testParam->m_sampleCount);
1651 	const deUint32 attachmentCount	   = getColorAttachmentCount(m_testParam->testType);
1652 	const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam);
1653 	// Loop over all samples in the same fragment
1654 
1655 	for (deUint32 rt = 0; (res == QP_TEST_RESULT_PASS) && rt < attachmentCount; rt++)
1656 	{
1657 		// Result of Helper Class test valid only for the rt 1
1658 		invalidateAlloc(m_vk, device, m_imageBuffer[rt]->getBoundMemory());
1659 
1660 		if (rt != 1 && isHelperClassTest(m_testParam->testType))
1661 		{
1662 			continue;
1663 		}
1664 
1665 		for (deUint32 fy = 0; (res == QP_TEST_RESULT_PASS) && fy < m_testParam->frameBufferSize; ++fy)
1666 		{
1667 			for (deUint32 fx = 0; (res == QP_TEST_RESULT_PASS) && fx < m_testParam->frameBufferSize; ++fx)
1668 			{
1669 				for (deUint32 fs = 0; (res == QP_TEST_RESULT_PASS) && fs < sampleCount; ++fs)
1670 				{
1671 					const deUint32 expectedValue = simulate(fx, fy, fs, rt);
1672 					const deUint32 resultValue	 = getResultValue(fx, fy, fs, rt);
1673 
1674 					if (isHelperClassTest(m_testParam->testType))
1675 					{
1676 						// ________      ________      ________
1677 						// 1|1|1|0|      0|0|*|1|      1|1|#|2|
1678 						// 1|1|0|0|      0|0|1|*|      1|1|2|#|
1679 						// 1|0|0|0|  =>  *|1|0|0|  =>  #|2|1|1|
1680 						// 0|0|0|0|      1|*|0|0|      2|#|1|1|
1681 						// ________      ________      ________
1682 						// raster       max(dx,dy)    result(+1)
1683 						// *(#): max(dx, dy) could be 0(1) or 1(2).
1684 						if (expectedValue != resultValue)
1685 						{
1686 							if (std::abs(static_cast<deInt32>(fx - fy)) != 1 || resultValue != kDerivative1)
1687 							{
1688 								res = QP_TEST_RESULT_FAIL;
1689 								break;
1690 							}
1691 						}
1692 					}
1693 					else if (vertexCountPerPatch == 6) // Fill full quad to the framebuffer
1694 					{
1695 						if (expectedValue != resultValue)
1696 						{
1697 							res = QP_TEST_RESULT_FAIL;
1698 							break;
1699 						}
1700 					}
1701 					else // Fill a triangle to the framebuffer, check half of framebuffer
1702 					{
1703 						if (fy > fx) // inside of triangle
1704 						{
1705 							if (expectedValue != resultValue) // not expected value
1706 							{
1707 								res = QP_TEST_RESULT_FAIL;
1708 								break;
1709 							}
1710 						}
1711 						else // outside of filling triangle or triangle edge
1712 						{
1713 							if (resultValue != 0 && resultValue != expectedValue) // can be not filling
1714 							{
1715 								res = QP_TEST_RESULT_FAIL;
1716 								break;
1717 							}
1718 						}
1719 					}
1720 				}
1721 			}
1722 		}
1723 	}
1724 
1725 	return tcu::TestStatus(res, qpGetTestResultName(res));
1726 }
1727 
rendering()1728 void ShaderTileImageTestInstance::rendering()
1729 {
1730 	const VkDevice device = m_context.getDevice();
1731 	const VkQueue  queue  = m_context.getUniversalQueue();
1732 
1733 	beginCommandBuffer(m_vk, *m_cmdBuffer);
1734 
1735 	// begin render pass
1736 	const VkClearValue clearValue	= {}; // { 0, 0, 0, 0 }
1737 	const VkClearValue dsClearValue = {}; // .depth = 0.0f, .stencil = 0
1738 	const VkRect2D	   renderArea	= { { 0, 0 }, { m_testParam->frameBufferSize, m_testParam->frameBufferSize } };
1739 
1740 	const deUint32 colorAttachmentCount = getColorAttachmentCount(m_testParam->testType);
1741 
1742 	std::vector<VkRenderingAttachmentInfoKHR> colorAttachments;
1743 	for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1744 	{
1745 		const VkRenderingAttachmentInfoKHR renderingAtachInfo = {
1746 			VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1747 			DE_NULL,										 // const void* pNext;
1748 			*m_imageColorView[colorIndex],					 // VkImageView imageView;
1749 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		 // VkImageLayout imageLayout;
1750 			VK_RESOLVE_MODE_NONE,							 // VkResolveModeFlagBits resolveMode;
1751 			DE_NULL,										 // VkImageView resolveImageView;
1752 			VK_IMAGE_LAYOUT_UNDEFINED,						 // VkImageLayout resolveImageLayout;
1753 			VK_ATTACHMENT_LOAD_OP_CLEAR,					 // VkAttachmentLoadOp loadOp;
1754 			VK_ATTACHMENT_STORE_OP_STORE,					 // VkAttachmentStoreOp storeOp;
1755 			clearValue,										 // VkClearValue clearValue;
1756 		};
1757 
1758 		colorAttachments.push_back(renderingAtachInfo);
1759 	}
1760 
1761 	const tcu::TextureFormat depthStencilFormat = mapVkFormat(m_testParam->depthStencilFormat);
1762 	const bool				 hasDepth			= tcu::hasDepthComponent(depthStencilFormat.order);
1763 	const bool				 hasStencil			= tcu::hasStencilComponent(depthStencilFormat.order);
1764 	VkImageLayout			 depthStencilLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1765 	VkImageAspectFlags		 depthStencilAspect = 0;
1766 	if (hasDepth && hasStencil)
1767 	{
1768 		depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
1769 		depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1770 	}
1771 	else if (hasDepth)
1772 	{
1773 		depthStencilLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1774 		depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT;
1775 	}
1776 	else if (hasStencil)
1777 	{
1778 		depthStencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1779 		depthStencilAspect = VK_IMAGE_ASPECT_STENCIL_BIT;
1780 	}
1781 
1782 	const VkRenderingAttachmentInfoKHR depthStencilAttachment = {
1783 		VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType			sType;
1784 		DE_NULL,										 // const void*				pNext;
1785 		*m_imageDepthStencilView,						 // VkImageView				imageView;
1786 		depthStencilLayout,								 // VkImageLayout			imageLayout;
1787 		VK_RESOLVE_MODE_NONE,							 // VkResolveModeFlagBits	resolveMode;
1788 		DE_NULL,										 // VkImageView				resolveImageView;
1789 		VK_IMAGE_LAYOUT_UNDEFINED,						 // VkImageLayout			resolveImageLayout;
1790 		VK_ATTACHMENT_LOAD_OP_CLEAR,					 // VkAttachmentLoadOp		loadOp;
1791 		VK_ATTACHMENT_STORE_OP_STORE,					 // VkAttachmentStoreOp		storeOp;
1792 		dsClearValue,									 // VkClearValue				clearValue;
1793 	};
1794 
1795 	const VkRenderingInfoKHR renderingInfo = {
1796 		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,			// VkStructureType sType;
1797 		DE_NULL,										// const void* pNext;
1798 		0,												// VkRenderingFlagsKHR flags;
1799 		renderArea,										// VkRect2D renderArea;
1800 		1u,												// deUint32 layerCount;
1801 		0u,												// deUint32 viewMask;
1802 		static_cast<deUint32>(colorAttachments.size()), // deUint32 colorAttachmentCount;
1803 		colorAttachments.data(),						// const VkRenderingAttachmentInfoKHR* pColorAttachments;
1804 		hasDepth ? &depthStencilAttachment : DE_NULL,	// const VkRenderingAttachmentInfoKHR* pDepthAttachment;
1805 		hasStencil ? &depthStencilAttachment : DE_NULL	// const VkRenderingAttachmentInfoKHR* pStencilAttachment;
1806 	};
1807 
1808 	for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1809 	{
1810 		transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT,
1811 						  VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 0,
1812 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1813 						  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
1814 	}
1815 
1816 	transition2DImage(m_vk, *m_cmdBuffer, *m_imageDepthStencil, depthStencilAspect, VK_IMAGE_LAYOUT_UNDEFINED,
1817 					  depthStencilLayout, 0, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
1818 					  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
1819 					  VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1820 
1821 	m_vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1822 
1823 	// vertex input setup
1824 	const VkBuffer vertexBuffer = m_vertexBuffer->object();
1825 
1826 	for (deUint32 drawIndex = 0; drawIndex < getDrawCallCount(m_testParam); drawIndex++)
1827 	{
1828 		// pipeline setup
1829 		if (drawIndex == 1 && isHelperClassTest(m_testParam->testType))
1830 		{
1831 			m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelineForHelperClass);
1832 		}
1833 		else
1834 		{
1835 			m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1836 		}
1837 
1838 		const deUint32 vertexCountPerPatch = getVertexCountPerPatch(m_testParam);
1839 		const deUint32 vertexCount = vertexCountPerPatch * getPatchesPerDrawCount(m_testParam->multiplePatchesPerDraw);
1840 		m_vk.cmdPushConstants(*m_cmdBuffer, *m_graphicsPipelineLayout,
1841 							  (VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT), 0, sizeof(deUint32),
1842 							  &drawIndex);
1843 
1844 		const VkDeviceSize vertexBufferOffset = (vertexCount * drawIndex) * sizeof(tcu::Vec2);
1845 		m_vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer, &vertexBufferOffset);
1846 
1847 		if (!m_testParam->coherent)
1848 		{
1849 			VkMemoryBarrier2KHR memoryBarrierForColor = {
1850 				VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR,				// sType
1851 				DE_NULL,											// pNext
1852 				VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// srcStageMask
1853 				VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT_KHR,			// srcAccessMask
1854 				VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR,// dstStageMask
1855 				VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT_KHR			// dstAccessMask
1856 			};
1857 
1858 			VkMemoryBarrier2KHR memoryBarrierForDepthStencil = {
1859 				VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR,				// sType
1860 				DE_NULL,											// pNext
1861 				VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
1862 					VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT,	// srcStageMask
1863 				VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT_KHR, // srcAccessMask
1864 				VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT |
1865 					VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT ,	// dstStageMask
1866 				VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT_KHR	// dstAccessMask
1867 			};
1868 
1869 			VkMemoryBarrier2KHR* memoryBarrier =
1870 				(m_testParam->testType == TestType::Depth) || (m_testParam->testType == TestType::Stencil) ?
1871 					&memoryBarrierForDepthStencil :
1872 					&memoryBarrierForColor;
1873 
1874 			VkDependencyInfoKHR dependencyInfo{
1875 				VK_STRUCTURE_TYPE_DEPENDENCY_INFO, // sType
1876 				DE_NULL,						   // pNext
1877 				VK_DEPENDENCY_BY_REGION_BIT,	   //dependency flags
1878 				1,								   //memory barrier count
1879 				memoryBarrier,					   //memory barrier
1880 				0,								   // bufferMemoryBarrierCount
1881 				DE_NULL,						   // pBufferMemoryBarriers
1882 				0,								   // imageMemoryBarrierCount
1883 				DE_NULL,						   // pImageMemoryBarriers
1884 			};
1885 			m_vk.cmdPipelineBarrier2(*m_cmdBuffer, &dependencyInfo);
1886 		}
1887 
1888 		m_vk.cmdDraw(*m_cmdBuffer, vertexCount, 1, 0, 0u);
1889 	}
1890 	m_vk.cmdEndRendering(*m_cmdBuffer);
1891 
1892 	for (deUint32 colorIndex = 0; colorIndex < colorAttachmentCount; colorIndex++)
1893 	{
1894 
1895 		transition2DImage(m_vk, *m_cmdBuffer, *m_imageColor[colorIndex], VK_IMAGE_ASPECT_COLOR_BIT,
1896 						  VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
1897 						  VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT,
1898 						  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1899 						  VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
1900 	}
1901 
1902 	VkMemoryBarrier memBarrier = {
1903 		VK_STRUCTURE_TYPE_MEMORY_BARRIER, // sType
1904 		DE_NULL,						  // pNext
1905 		0u,								  // srcAccessMask
1906 		0u,								  // dstAccessMask
1907 	};
1908 	memBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
1909 	memBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT;
1910 	m_vk.cmdPipelineBarrier(*m_cmdBuffer,
1911 							VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
1912 							VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
1913 
1914 	m_vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
1915 
1916 	// Copy color images to buffer memory
1917 	for (deUint32 attachmentIndex = 0; attachmentIndex < colorAttachmentCount; attachmentIndex++)
1918 	{
1919 		m_vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipelineLayout, 0u, 1,
1920 								   &*m_descriptorSets[attachmentIndex], 0u, DE_NULL);
1921 
1922 		m_vk.cmdDispatch(*m_cmdBuffer, m_testParam->frameBufferSize, m_testParam->frameBufferSize, 1);
1923 	}
1924 	memBarrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
1925 	memBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
1926 	m_vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0, 1,
1927 							&memBarrier, 0, DE_NULL, 0, DE_NULL);
1928 
1929 	VK_CHECK(m_vk.endCommandBuffer(*m_cmdBuffer));
1930 
1931 	submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get());
1932 }
1933 
formatToName(VkFormat format)1934 std::string formatToName(VkFormat format)
1935 {
1936 	const std::string formatStr = de::toString(format);
1937 	const std::string prefix	= "VK_FORMAT_";
1938 
1939 	DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
1940 
1941 	return de::toLower(formatStr.substr(prefix.length()));
1942 }
1943 
createShaderTileImageTestVariations(tcu::TestContext & testCtx,tcu::TestCaseGroup * gr)1944 void createShaderTileImageTestVariations(tcu::TestContext& testCtx, tcu::TestCaseGroup* gr)
1945 {
1946 	struct TestTypeParam
1947 	{
1948 		TestType	value;
1949 		const char* name;
1950 	};
1951 
1952 	struct BoolParam
1953 	{
1954 		bool		value;
1955 		const char* name;
1956 	};
1957 
1958 	struct VkSampleCountFlagParam
1959 	{
1960 		VkSampleCountFlagBits value;
1961 		const char*			  name;
1962 	};
1963 
1964 	const std::vector<BoolParam> coherentParams = { { true, "coherent" }, { false, "non_coherent" } };
1965 
1966 	const std::vector<TestTypeParam> testTypeParams = {
1967 		{ TestType::Color, "color" },
1968 		{ TestType::MultiRenderTarget, "mrt" },
1969 		{ TestType::MultiRenderTargetDynamicIndex, "mrt_dynamic_index" },
1970 		{ TestType::MsaaSampleMask, "msaa_sample_mask" },
1971 		{ TestType::HelperClassColor, "helper_class_color" },
1972 		{ TestType::HelperClassDepth, "helper_class_depth" },
1973 		{ TestType::HelperClassStencil, "helper_class_stencil" },
1974 		{ TestType::Depth, "depth" },
1975 		{ TestType::Stencil, "stencil" },
1976 	};
1977 
1978 	const std::vector<VkSampleCountFlagParam> sampleCountParams = {
1979 		{ VK_SAMPLE_COUNT_1_BIT, "samples_1" },	  { VK_SAMPLE_COUNT_2_BIT, "samples_2" },
1980 		{ VK_SAMPLE_COUNT_4_BIT, "samples_4" },	  { VK_SAMPLE_COUNT_8_BIT, "samples_8" },
1981 		{ VK_SAMPLE_COUNT_16_BIT, "samples_16" }, { VK_SAMPLE_COUNT_32_BIT, "samples_32" },
1982 	};
1983 
1984 	const std::vector<BoolParam> multiDrawsParams = { { false, "single_draw" }, { true, "multi_draws" } };
1985 
1986 	const std::vector<BoolParam> multiPatchParams = { { false, "single_patch" }, { true, "multi_patches" } };
1987 
1988 	const std::vector<VkFormat> formats = { VK_FORMAT_R5G6B5_UNORM_PACK16,
1989 											VK_FORMAT_R8G8_UNORM,
1990 											VK_FORMAT_R8G8_SNORM,
1991 											VK_FORMAT_R8G8_UINT,
1992 											VK_FORMAT_R8G8_SINT,
1993 											VK_FORMAT_R8G8B8A8_UNORM,
1994 											VK_FORMAT_R8G8B8A8_SNORM,
1995 											VK_FORMAT_R8G8B8A8_UINT,
1996 											VK_FORMAT_R8G8B8A8_SINT,
1997 											VK_FORMAT_R8G8B8A8_SRGB,
1998 											VK_FORMAT_A8B8G8R8_UNORM_PACK32,
1999 											VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2000 											VK_FORMAT_A8B8G8R8_UINT_PACK32,
2001 											VK_FORMAT_A8B8G8R8_SINT_PACK32,
2002 											VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2003 											VK_FORMAT_B8G8R8A8_UNORM,
2004 											VK_FORMAT_B8G8R8A8_SRGB,
2005 											VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2006 											VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2007 											VK_FORMAT_A2B10G10R10_UINT_PACK32,
2008 											VK_FORMAT_R16G16_UNORM,
2009 											VK_FORMAT_R16G16_SNORM,
2010 											VK_FORMAT_R16G16_UINT,
2011 											VK_FORMAT_R16G16_SINT,
2012 											VK_FORMAT_R16G16_SFLOAT,
2013 											VK_FORMAT_R16G16B16A16_UNORM,
2014 											VK_FORMAT_R16G16B16A16_SNORM,
2015 											VK_FORMAT_R16G16B16A16_UINT,
2016 											VK_FORMAT_R16G16B16A16_SINT,
2017 											VK_FORMAT_R16G16B16A16_SFLOAT,
2018 											VK_FORMAT_R32G32_UINT,
2019 											VK_FORMAT_R32G32_SINT,
2020 											VK_FORMAT_R32G32_SFLOAT,
2021 											VK_FORMAT_R32G32B32A32_UINT,
2022 											VK_FORMAT_R32G32B32A32_SINT,
2023 											VK_FORMAT_R32G32B32A32_SFLOAT,
2024 											VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
2025 
2026 											VK_FORMAT_D16_UNORM,
2027 											VK_FORMAT_X8_D24_UNORM_PACK32,
2028 											VK_FORMAT_D32_SFLOAT,
2029 											VK_FORMAT_S8_UINT,
2030 											VK_FORMAT_D16_UNORM_S8_UINT,
2031 											VK_FORMAT_D24_UNORM_S8_UINT,
2032 											VK_FORMAT_D32_SFLOAT_S8_UINT };
2033 
2034 	tcu::TestCaseGroup*				 subGroup = nullptr;
2035 	std::vector<tcu::TestCaseGroup*> testGroupStack;
2036 	testGroupStack.push_back(gr);
2037 
2038 	for (const BoolParam& coherentParam : coherentParams)
2039 	{
2040 		subGroup = (new tcu::TestCaseGroup(testCtx, coherentParam.name));
2041 		testGroupStack.back()->addChild(subGroup);
2042 		testGroupStack.push_back(subGroup);
2043 		for (const TestTypeParam& testTypeParam : testTypeParams)
2044 		{
2045 			subGroup = new tcu::TestCaseGroup(testCtx, testTypeParam.name);
2046 			testGroupStack.back()->addChild(subGroup);
2047 			testGroupStack.push_back(subGroup);
2048 
2049 			for (const VkSampleCountFlagParam& sampleCountParam : sampleCountParams)
2050 			{
2051 				if (testTypeParam.value == TestType::MsaaSampleMask && sampleCountParam.value == VK_SAMPLE_COUNT_1_BIT)
2052 				{
2053 					// SampleMask test requires MSAA
2054 					continue;
2055 				}
2056 				if (isHelperClassTest(testTypeParam.value) && sampleCountParam.value != VK_SAMPLE_COUNT_1_BIT)
2057 				{
2058 					// HelperClass test designed for non msaa case
2059 					continue;
2060 				}
2061 				subGroup = new tcu::TestCaseGroup(testCtx, sampleCountParam.name);
2062 				testGroupStack.back()->addChild(subGroup);
2063 				testGroupStack.push_back(subGroup);
2064 
2065 				for (const BoolParam& multiDrawsParam : multiDrawsParams)
2066 				{
2067 					if (isHelperClassTest(testTypeParam.value) && multiDrawsParam.value)
2068 					{
2069 						// helper class 2 draws but works like single draw call
2070 						continue;
2071 					}
2072 
2073 					subGroup = new tcu::TestCaseGroup(testCtx, multiDrawsParam.name);
2074 					testGroupStack.back()->addChild(subGroup);
2075 					testGroupStack.push_back(subGroup);
2076 
2077 					for (const BoolParam& multiPatchParam : multiPatchParams)
2078 					{
2079 						if (!coherentParam.value && multiPatchParam.value) // cannot guarantee
2080 						{
2081 							continue;
2082 						}
2083 						if (isHelperClassTest(testTypeParam.value) && multiPatchParam.value)
2084 						{
2085 							// helper class works on single patch cases
2086 							continue;
2087 						}
2088 
2089 						subGroup = new tcu::TestCaseGroup(testCtx, multiPatchParam.name);
2090 						testGroupStack.back()->addChild(subGroup);
2091 						testGroupStack.push_back(subGroup);
2092 
2093 						for (VkFormat format : formats)
2094 						{
2095 							tcu::TestCaseGroup* curGroup   = testGroupStack.back();
2096 							const bool			hasDepth   = tcu::hasDepthComponent(mapVkFormat(format).order);
2097 							const bool			hasStencil = tcu::hasStencilComponent(mapVkFormat(format).order);
2098 							std::string			name	   = formatToName(format);
2099 
2100 							TestParam testParam				 = {};
2101 							testParam.coherent				 = coherentParam.value;
2102 							testParam.testType				 = testTypeParam.value;
2103 							testParam.colorFormat			 = VK_FORMAT_R32G32B32A32_UINT;
2104 							testParam.depthStencilFormat	 = VK_FORMAT_D32_SFLOAT_S8_UINT;
2105 							testParam.m_sampleCount			 = sampleCountParam.value;
2106 							testParam.multipleDrawCalls		 = multiDrawsParam.value;
2107 							testParam.multiplePatchesPerDraw = multiPatchParam.value;
2108 							testParam.frameBufferSize		 = kImageSize;
2109 							if (testTypeParam.value == TestType::Depth ||
2110 								testTypeParam.value == TestType::HelperClassDepth)
2111 							{
2112 								if (hasDepth)
2113 								{
2114 									testParam.depthStencilFormat = format;
2115 									curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2116 								}
2117 							}
2118 							else if (testTypeParam.value == TestType::Stencil ||
2119 									 testTypeParam.value == TestType::HelperClassStencil)
2120 							{
2121 								if (hasStencil)
2122 								{
2123 									testParam.depthStencilFormat = format;
2124 									curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2125 								}
2126 							}
2127 							else
2128 							{
2129 								if (!hasStencil && !hasDepth)
2130 								{
2131 									if (isHelperClassTest(testTypeParam.value) && isNormalizedColorFormat(format))
2132 									{
2133 										// reduce helper class test cases and complexities
2134 										continue;
2135 									}
2136 
2137 									const deUint32 maxResultValue =
2138 										(getDrawCallCount(&testParam) *
2139 											 getPatchesPerDrawCount(testParam.multiplePatchesPerDraw) *
2140 											 getColorAttachmentCount(testParam.testType) +
2141 										 getSampleCount(testParam.m_sampleCount));
2142 									const tcu::IVec4 channelBitDepth =
2143 										tcu::getTextureFormatBitDepth(mapVkFormat(format));
2144 
2145 									// color output precision is less than test case.
2146 									// ban the overflow problem.
2147 									if (static_cast<deUint32>(1 << (channelBitDepth.y() - 1)) > maxResultValue)
2148 									{
2149 										testParam.colorFormat = format;
2150 										curGroup->addChild(new ShaderTileImageTestCase(testCtx, name, testParam));
2151 									}
2152 								}
2153 							}
2154 						} // formats
2155 						testGroupStack.pop_back();
2156 					} // multiPatchParams
2157 					testGroupStack.pop_back();
2158 				} // multiDrawsParams
2159 				testGroupStack.pop_back();
2160 			} // sampleCountParams
2161 			testGroupStack.pop_back();
2162 		} // testTypeParams
2163 		testGroupStack.pop_back();
2164 	} // coherentParams
2165 }
2166 } // namespace
2167 // anonymous namespace
2168 
createShaderTileImageTests(tcu::TestContext & testCtx)2169 tcu::TestCaseGroup* createShaderTileImageTests(tcu::TestContext& testCtx)
2170 {
2171 	/* Add the color tests */
2172 	tcu::TestCaseGroup* gr = new tcu::TestCaseGroup(testCtx, "shader_tile_image");
2173 	createShaderTileImageTestVariations(testCtx, gr);
2174 
2175 	return gr;
2176 }
2177 
2178 } // namespace rasterization
2179 } // namespace vkt
2180