• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  * Copyright (c) 2016 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Shader builtin variable tests.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vktShaderRenderBuiltinVarTests.hpp"
27 
28 #include "tcuFloat.hpp"
29 #include "deUniquePtr.hpp"
30 #include "vkDefs.hpp"
31 #include "vktShaderRender.hpp"
32 #include "gluShaderUtil.hpp"
33 #include "tcuImageCompare.hpp"
34 #include "tcuStringTemplate.hpp"
35 #include "tcuTextureUtil.hpp"
36 #include "tcuTestLog.hpp"
37 #include "vktDrawUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "vkCmdUtil.hpp"
42 
43 #include "deMath.h"
44 #include "deRandom.hpp"
45 
46 #include <map>
47 
48 using namespace std;
49 using namespace tcu;
50 using namespace vk;
51 using namespace de;
52 
53 namespace vkt
54 {
55 using namespace drawutil;
56 
57 namespace sr
58 {
59 
60 namespace
61 {
62 
63 enum
64 {
65 	FRONTFACE_RENDERWIDTH			= 16,
66 	FRONTFACE_RENDERHEIGHT			= 16
67 };
68 
69 class FrontFacingVertexShader : public rr::VertexShader
70 {
71 public:
FrontFacingVertexShader(void)72 	FrontFacingVertexShader (void)
73 		: rr::VertexShader(1, 0)
74 	{
75 		m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
76 	}
77 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const78 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
79 	{
80 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
81 		{
82 			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
83 																	 packets[packetNdx]->instanceNdx,
84 																	 packets[packetNdx]->vertexNdx);
85 		}
86 	}
87 };
88 
89 class FrontFacingFragmentShader : public rr::FragmentShader
90 {
91 public:
FrontFacingFragmentShader(void)92 	FrontFacingFragmentShader (void)
93 		: rr::FragmentShader(0, 1)
94 	{
95 		m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
96 	}
97 
shadeFragments(rr::FragmentPacket *,const int numPackets,const rr::FragmentShadingContext & context) const98 	void shadeFragments (rr::FragmentPacket* , const int numPackets, const rr::FragmentShadingContext& context) const
99 	{
100 		tcu::Vec4 color;
101 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
102 		{
103 			for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
104 			{
105 				if (context.visibleFace == rr::FACETYPE_FRONT)
106 					color = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
107 				else
108 					color = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
109 				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, color);
110 			}
111 		}
112 	}
113 };
114 
115 class BuiltinGlFrontFacingCaseInstance : public ShaderRenderCaseInstance
116 {
117 public:
118 					BuiltinGlFrontFacingCaseInstance	(Context& context, VkPrimitiveTopology topology);
119 
120 	TestStatus		iterate								(void);
121 private:
122 	const VkPrimitiveTopology							m_topology;
123 };
124 
BuiltinGlFrontFacingCaseInstance(Context & context,VkPrimitiveTopology topology)125 BuiltinGlFrontFacingCaseInstance::BuiltinGlFrontFacingCaseInstance (Context& context, VkPrimitiveTopology topology)
126 	: ShaderRenderCaseInstance	(context)
127 	, m_topology				(topology)
128 {
129 }
130 
131 
iterate(void)132 TestStatus BuiltinGlFrontFacingCaseInstance::iterate (void)
133 {
134 	TestLog&							log				= m_context.getTestContext().getLog();
135 	std::vector<Vec4>					vertices;
136 	std::vector<VulkanShader>			shaders;
137 	std::shared_ptr<rr::VertexShader>	vertexShader	= std::make_shared<FrontFacingVertexShader>();
138 	std::shared_ptr<rr::FragmentShader>	fragmentShader	= std::make_shared<FrontFacingFragmentShader>();
139 	std::string							testDesc;
140 
141 	vertices.push_back(Vec4( -0.75f,	-0.75f,	0.0f,	1.0f));
142 	vertices.push_back(Vec4(  0.0f,		-0.75f,	0.0f,	1.0f));
143 	vertices.push_back(Vec4( -0.37f,	0.75f,	0.0f,	1.0f));
144 	vertices.push_back(Vec4(  0.37f,	0.75f,	0.0f,	1.0f));
145 	vertices.push_back(Vec4(  0.75f,	-0.75f,	0.0f,	1.0f));
146 	vertices.push_back(Vec4(  0.0f,		-0.75f,	0.0f,	1.0f));
147 
148 	shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert")));
149 	shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("frag")));
150 
151 	testDesc = "gl_FrontFacing " + getPrimitiveTopologyShortName(m_topology) + " ";
152 
153 	FrameBufferState			frameBufferState	(FRONTFACE_RENDERWIDTH, FRONTFACE_RENDERHEIGHT);
154 	PipelineState				pipelineState		(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
155 	DrawCallData				drawCallData		(m_topology, vertices);
156 	VulkanProgram				vulkanProgram		(shaders);
157 	VulkanDrawContext			dc					(m_context, frameBufferState);
158 	dc.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
159 	dc.draw();
160 
161 	ReferenceDrawContext		refDrawContext(frameBufferState);
162 	refDrawContext.registerDrawObject(pipelineState, vertexShader, fragmentShader, drawCallData);
163 	refDrawContext.draw();
164 
165 	log << TestLog::Image( "reference",
166 							"reference",
167 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
168 									refDrawContext.getColorPixels().getFormat()),
169 									refDrawContext.getColorPixels().getWidth(),
170 									refDrawContext.getColorPixels().getHeight(),
171 									1,
172 									refDrawContext.getColorPixels().getDataPtr()));
173 
174 	log << TestLog::Image(	"result",
175 							"result",
176 							tcu::ConstPixelBufferAccess(tcu::TextureFormat(
177 									dc.getColorPixels().getFormat()),
178 									dc.getColorPixels().getWidth(),
179 									dc.getColorPixels().getHeight(),
180 									1,
181 									dc.getColorPixels().getDataPtr()));
182 
183 	if (tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
184 												  "ComparisonResult",
185 												  "Image comparison result",
186 												  refDrawContext.getColorPixels(),
187 												  dc.getColorPixels(),
188 												  UVec4(0u),
189 												  IVec3(1,1,0),
190 												  false,
191 												  tcu::COMPARE_LOG_RESULT))
192 	{
193 		testDesc += "passed";
194 		return tcu::TestStatus::pass(testDesc.c_str());
195 	}
196 	else
197 	{
198 		testDesc += "failed";
199 		return tcu::TestStatus::fail(testDesc.c_str());
200 	}
201 }
202 
203 class BuiltinGlFrontFacingCase : public TestCase
204 {
205 public:
206 								BuiltinGlFrontFacingCase	(TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description);
207 	virtual						~BuiltinGlFrontFacingCase	(void);
208 
209 	void						initPrograms				(SourceCollections& dst) const;
210 	void						checkSupport				(Context& context) const;
211 	TestInstance*				createInstance				(Context& context) const;
212 
213 private:
214 								BuiltinGlFrontFacingCase	(const BuiltinGlFrontFacingCase&);	// not allowed!
215 	BuiltinGlFrontFacingCase&	operator=					(const BuiltinGlFrontFacingCase&);	// not allowed!
216 
217 	const VkPrimitiveTopology	m_topology;
218 };
219 
BuiltinGlFrontFacingCase(TestContext & testCtx,VkPrimitiveTopology topology,const char * name,const char * description)220 BuiltinGlFrontFacingCase::BuiltinGlFrontFacingCase (TestContext& testCtx, VkPrimitiveTopology topology, const char* name, const char* description)
221 	: TestCase					(testCtx, name, description)
222 	, m_topology				(topology)
223 {
224 }
225 
~BuiltinGlFrontFacingCase(void)226 BuiltinGlFrontFacingCase::~BuiltinGlFrontFacingCase (void)
227 {
228 }
229 
initPrograms(SourceCollections & programCollection) const230 void BuiltinGlFrontFacingCase::initPrograms (SourceCollections& programCollection) const
231 {
232 	{
233 		std::ostringstream vertexSource;
234 		vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
235 			<< "\n"
236 			<< "layout(location = 0) in highp vec4 position;\n"
237 			<< "void main()\n"
238 			<< "{\n"
239 			<< "gl_Position = position;\n"
240 			<< "gl_PointSize = 1.0;\n"
241 			<< "}\n";
242 		programCollection.glslSources.add("vert") << glu::VertexSource(vertexSource.str());
243 	}
244 
245 	{
246 		std::ostringstream fragmentSource;
247 		fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
248 			<< "\n"
249 			<< "layout(location = 0) out mediump vec4 color;\n"
250 			<< "void main()\n"
251 			<< "{\n"
252 			<< "if (gl_FrontFacing)\n"
253 			<< "	color = vec4(1.0, 0.0, 0.0, 1.0);\n"
254 			<< "else\n"
255 			<< "	color = vec4(0.0, 1.0, 0.0, 1.0);\n"
256 			<< "}\n";
257 		programCollection.glslSources.add("frag") << glu::FragmentSource(fragmentSource.str());
258 	}
259 }
260 
checkSupport(Context & context) const261 void BuiltinGlFrontFacingCase::checkSupport (Context& context) const
262 {
263 #ifndef CTS_USES_VULKANSC
264 	if (m_topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN &&
265 		context.isDeviceFunctionalitySupported("VK_KHR_portability_subset") &&
266 		!context.getPortabilitySubsetFeatures().triangleFans)
267 	{
268 		TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Triangle fans are not supported by this implementation");
269 	}
270 #else
271 	DE_UNREF(context);
272 #endif // CTS_USES_VULKANSC
273 }
274 
createInstance(Context & context) const275 TestInstance* BuiltinGlFrontFacingCase::createInstance (Context& context) const
276 {
277 	return new BuiltinGlFrontFacingCaseInstance(context, m_topology);
278 }
279 
280 class BuiltinFragDepthCaseInstance : public TestInstance
281 {
282 public:
283 	enum
284 	{
285 		RENDERWIDTH		= 16,
286 		RENDERHEIGHT	= 16
287 	};
288 					BuiltinFragDepthCaseInstance		(Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples);
289 	TestStatus		iterate								(void);
290 
291 	bool			validateDepthBuffer					(const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const;
292 private:
293 	const VkPrimitiveTopology		m_topology;
294 	const VkFormat					m_format;
295 	const bool						m_largeDepthEnable;
296 	const float						m_defaultDepthValue;
297 	const bool						m_depthClampEnable;
298 	const VkSampleCountFlagBits		m_samples;
299 	const tcu::UVec2				m_renderSize;
300 	const float						m_largeDepthBase;
301 };
302 
BuiltinFragDepthCaseInstance(Context & context,VkPrimitiveTopology topology,VkFormat format,bool largeDepthEnable,float defaultDepth,bool depthClampEnable,const VkSampleCountFlagBits samples)303 BuiltinFragDepthCaseInstance::BuiltinFragDepthCaseInstance (Context& context, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, float defaultDepth, bool depthClampEnable, const VkSampleCountFlagBits samples)
304 	: TestInstance			(context)
305 	, m_topology			(topology)
306 	, m_format				(format)
307 	, m_largeDepthEnable	(largeDepthEnable)
308 	, m_defaultDepthValue	(defaultDepth)
309 	, m_depthClampEnable	(depthClampEnable)
310 	, m_samples				(samples)
311 	, m_renderSize			(RENDERWIDTH, RENDERHEIGHT)
312 	, m_largeDepthBase		(20.0f)
313 {
314 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
315 	const VkPhysicalDevice		physicalDevice		= m_context.getPhysicalDevice();
316 
317 	try
318 	{
319 		VkImageFormatProperties		imageFormatProperties;
320 		VkFormatProperties			formatProperties;
321 
322 		if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
323 			throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
324 
325 		if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
326 			throw tcu::NotSupportedError("sampleRateShading not supported");
327 
328 		imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, m_format, VK_IMAGE_TYPE_2D,
329 				VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, (VkImageCreateFlags)0);
330 
331 		if ((imageFormatProperties.sampleCounts & m_samples) == 0)
332 			throw tcu::NotSupportedError("Image format and sample count not supported");
333 
334 		formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R8G8B8A8_UINT);
335 
336 		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
337 			throw tcu::NotSupportedError("MarkerImage format not supported as storage image");
338 
339 		if (m_largeDepthEnable && !de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), "VK_EXT_depth_range_unrestricted"))
340 			throw tcu::NotSupportedError("large_depth test variants require the VK_EXT_depth_range_unrestricted extension");
341 
342 		if (m_context.getDeviceFeatures().depthClamp == VK_FALSE && m_depthClampEnable)
343 			throw tcu::NotSupportedError("Depthclamp is not supported.");
344 	}
345 	catch (const vk::Error& e)
346 	{
347 		if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
348 			throw tcu::NotSupportedError("Image format not supported");
349 		else
350 			throw;
351 
352 	}
353 }
354 
iterate(void)355 TestStatus BuiltinFragDepthCaseInstance::iterate (void)
356 {
357 	const VkDevice					device				= m_context.getDevice();
358 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
359 	const VkQueue					queue				= m_context.getUniversalQueue();
360 	Allocator&						allocator			= m_context.getDefaultAllocator();
361 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
362 	TestLog&						log					= m_context.getTestContext().getLog();
363 	const deUint32					scale				= 4;										// To account for std140 stride
364 	const VkDeviceSize				pixelCount			= m_renderSize.x() * m_renderSize.y();
365 	std::string						testDesc;
366 	Move<VkImage>					depthResolveImage;
367 	Move<VkImageView>				depthResolveImageView;
368 	MovePtr<Allocation>				depthResolveAllocation;
369 	Move<VkImage>					depthImage;
370 	Move<VkImageView>				depthImageView;
371 	MovePtr<Allocation>				depthImageAllocation;
372 	Move<VkBuffer>					controlBuffer;
373 	MovePtr<Allocation>				controlBufferAllocation;
374 	Move<VkImage>					markerImage;
375 	Move<VkImageView>				markerImageView;
376 	MovePtr<Allocation>				markerImageAllocation;
377 	Move<VkBuffer>					markerBuffer;
378 	MovePtr<Allocation>				markerBufferAllocation;
379 	Move<VkBuffer>					validationBuffer;
380 	MovePtr<Allocation>				validationAlloc;
381 	MovePtr<Allocation>				depthInitAllocation;
382 	Move<VkCommandPool>				cmdPool;
383 	Move<VkCommandBuffer>			transferCmdBuffer;
384 	Move<VkSampler>					depthSampler;
385 
386 	// Create Buffer/Image for validation
387 	{
388 		VkFormat	resolvedBufferFormat = VK_FORMAT_R32_SFLOAT;
389 		const VkBufferCreateInfo validationBufferCreateInfo =
390 		{
391 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,										// VkStructureType		sType
392 			DE_NULL,																	// const void*			pNext
393 			(VkBufferCreateFlags)0,														// VkBufferCreateFlags	flags
394 			m_samples * pixelCount * getPixelSize(mapVkFormat(resolvedBufferFormat)),	// VkDeviceSize			size
395 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,											// VkBufferUsageFlags	usage
396 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode		sharingMode
397 			0u,																			// uint32_t				queueFamilyIndexCount,
398 			DE_NULL																		// const uint32_t*		pQueueFamilyIndices
399 		};
400 
401 		validationBuffer = createBuffer(vk, device, &validationBufferCreateInfo);
402 		validationAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *validationBuffer), MemoryRequirement::HostVisible);
403 		VK_CHECK(vk.bindBufferMemory(device, *validationBuffer, validationAlloc->getMemory(), validationAlloc->getOffset()));
404 
405 		const VkImageCreateInfo depthResolveImageCreateInfo =
406 		{
407 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,								// VkStructureType			sType
408 			DE_NULL,															// const void*				pNext
409 			(VkImageCreateFlags)0,												// VkImageCreateFlags		flags
410 			VK_IMAGE_TYPE_2D,													// VkIMageType				imageType
411 			resolvedBufferFormat,												// VkFormat					format
412 			makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1u),	// VkExtent3D				extent
413 			1u,																	// uint32_t					mipLevels
414 			1u,																	// uint32_t					arrayLayers
415 			VK_SAMPLE_COUNT_1_BIT,												// VkSampleCountFlagsBits	samples
416 			VK_IMAGE_TILING_OPTIMAL,											// VkImageTiling			tiling
417 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |									// VkImageUsageFlags		usage
418 			VK_IMAGE_USAGE_STORAGE_BIT |
419 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
420 			VK_SHARING_MODE_EXCLUSIVE,											// VkSharingMode			sharingMode
421 			0u,																	// uint32_t					queueFamilyIndexCount
422 			DE_NULL,															// const uint32_t			pQueueFamilyIndices
423 			VK_IMAGE_LAYOUT_UNDEFINED											// VkImageLayout			initialLayout
424 		};
425 
426 		depthResolveImage = createImage(vk, device, &depthResolveImageCreateInfo, DE_NULL);
427 		depthResolveAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthResolveImage), MemoryRequirement::Any);
428 		VK_CHECK(vk.bindImageMemory(device, *depthResolveImage, depthResolveAllocation->getMemory(), depthResolveAllocation->getOffset()));
429 
430 		const VkImageViewCreateInfo depthResolveImageViewCreateInfo =
431 		{
432 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,								// VkStructureType			sType
433 			DE_NULL,																// const void*				pNext
434 			(VkImageViewCreateFlags)0,												// VkImageViewCreateFlags	flags
435 			*depthResolveImage,														// VkImage					image
436 			VK_IMAGE_VIEW_TYPE_2D,													// VkImageViewType			type
437 			resolvedBufferFormat,													// VkFormat					format
438 			makeComponentMappingRGBA(),												// VkComponentMapping		componentMapping
439 			makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)	// VkImageSUbresourceRange	subresourceRange
440 		};
441 
442 		depthResolveImageView = createImageView(vk, device, &depthResolveImageViewCreateInfo, DE_NULL);
443 	}
444 
445 	// Marker Buffer
446 	{
447 		const VkDeviceSize	size			= m_samples * m_renderSize.x() * m_renderSize.y() * getPixelSize(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT));
448 
449 		const VkBufferCreateInfo markerBufferCreateInfo =
450 		{
451 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,			// VkStructureType			sType
452 			DE_NULL,										// const void*				pNext
453 			(VkBufferCreateFlags)0,							// VkBufferCreateFlags		flags
454 			size,											// VkDeviceSize				size
455 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,				// VkBufferUsageFlags		usage
456 			VK_SHARING_MODE_EXCLUSIVE,						// VkSharingMode			sharingMode
457 			0u,												// uint32_t					queueFamilyIndexCount
458 			DE_NULL											// const uint32_t*			pQueueFamilyIndices
459 		};
460 
461 		markerBuffer = createBuffer(vk, device, &markerBufferCreateInfo, DE_NULL);
462 		markerBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *markerBuffer), MemoryRequirement::HostVisible);
463 		VK_CHECK(vk.bindBufferMemory(device, *markerBuffer, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset()));
464 
465 		const VkImageCreateInfo markerImageCreateInfo =
466 		{
467 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,							// VkStructureType			sType
468 			DE_NULL,														// const void*				pNext
469 			(VkImageCreateFlags)0,											// VkImageCreateFlags		flags
470 			VK_IMAGE_TYPE_2D,												// VkImageType				imageType
471 			VK_FORMAT_R8G8B8A8_UINT,										// VkFormat					format
472 			makeExtent3D(m_samples * m_renderSize.x(), m_renderSize.y(), 1),// VkExtent3D				extent
473 			1u,																// uint32_t					mipLevels
474 			1u,																// uint32_t					arrayLayers
475 			VK_SAMPLE_COUNT_1_BIT,											// VkSampleCountFlagsBit	smaples
476 			VK_IMAGE_TILING_OPTIMAL,										// VkImageTiling			tiling
477 			VK_IMAGE_USAGE_STORAGE_BIT |									// VkImageUsageFlags		usage
478 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
479 			VK_IMAGE_USAGE_TRANSFER_DST_BIT,
480 			VK_SHARING_MODE_EXCLUSIVE,										// VkSharingMode			sharing
481 			0u,																// uint32_t					queueFamilyIndexCount
482 			DE_NULL,														// const uint32_t*			pQueueFamilyIndices
483 			VK_IMAGE_LAYOUT_UNDEFINED										// VkImageLayout			initialLayout
484 		};
485 
486 		markerImage = createImage(vk, device, &markerImageCreateInfo, DE_NULL);
487 		markerImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *markerImage), MemoryRequirement::Any);
488 		VK_CHECK(vk.bindImageMemory(device, *markerImage, markerImageAllocation->getMemory(), markerImageAllocation->getOffset()));
489 
490 		const VkImageViewCreateInfo markerViewCreateInfo =
491 		{
492 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType
493 			DE_NULL,												// const void*				pNext
494 			(VkImageViewCreateFlags)0,								// VkImageViewCreateFlags	flags
495 			*markerImage,											// VkImage					image
496 			VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType
497 			VK_FORMAT_R8G8B8A8_UINT,								// VkFormat					format
498 			makeComponentMappingRGBA(),								// VkComponentMapping		components
499 			makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)
500 		};
501 
502 		markerImageView = createImageView(vk, device, &markerViewCreateInfo, DE_NULL);
503 	}
504 
505 	// Control Buffer
506 	{
507 		const VkBufferCreateInfo controlBufferCreateInfo =
508 		{
509 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,					// VkStructureType		sType
510 			DE_NULL,												// const void*			pNext
511 			(VkBufferCreateFlags)0,									// VkBufferCreateFlags	flags
512 			pixelCount * sizeof(float)* scale,						// VkDeviceSize			size
513 			VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,						// VkBufferUsageFlags	usage
514 			VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode		sharingMode
515 			0u,														// deUint32				queueFamilyIndexCount
516 
517 			DE_NULL													// pQueueFamilyIndices
518 		};
519 
520 		controlBuffer = createBuffer(vk, device, &controlBufferCreateInfo, DE_NULL);
521 		controlBufferAllocation = allocator.allocate( getBufferMemoryRequirements(vk, device, *controlBuffer), MemoryRequirement::HostVisible);
522 		VK_CHECK(vk.bindBufferMemory(device, *controlBuffer, controlBufferAllocation->getMemory(), controlBufferAllocation->getOffset()));
523 
524 		{
525 			float* bufferData = (float*)(controlBufferAllocation->getHostPtr());
526 			float sign = m_depthClampEnable ? -1.0f : 1.0f;
527 			for (deUint32 ndx = 0; ndx < m_renderSize.x() * m_renderSize.y(); ndx++)
528 			{
529 				bufferData[ndx * scale] = (float)ndx / 256.0f * sign;
530 				if (m_largeDepthEnable)
531 					bufferData[ndx * scale] += m_largeDepthBase;
532 			}
533 
534 			const VkMappedMemoryRange range =
535 			{
536 				VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
537 				DE_NULL,
538 				controlBufferAllocation->getMemory(),
539 				0u,
540 				VK_WHOLE_SIZE
541 			};
542 
543 			VK_CHECK(vk.flushMappedMemoryRanges(device, 1u, &range));
544 		}
545 	}
546 
547 	// Depth Buffer
548 	{
549 		VkImageSubresourceRange depthSubresourceRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u);
550 		const VkImageCreateInfo depthImageCreateInfo	=
551 		{
552 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType
553 			DE_NULL,												// const void*				pNext
554 			(VkImageCreateFlags)0,									// VkImageCreateFlags		flags
555 			VK_IMAGE_TYPE_2D,										// VkImageType				imageType
556 			m_format,												// VkFormat					format
557 			makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u),	// VkExtent3D				extent
558 			1u,														// uint32_t					mipLevels
559 			1u,														// uint32_t					arrayLayers
560 			m_samples,												// VkSampleCountFlagsBits	samples
561 			VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling
562 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
563 			VK_IMAGE_USAGE_TRANSFER_DST_BIT |
564 			VK_IMAGE_USAGE_SAMPLED_BIT      |
565 			VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,			// VkImageUsageFlags		usage
566 			VK_SHARING_MODE_EXCLUSIVE,								// VkShaderingMode			sharingMode
567 			0u,														// uint32_t					queueFamilyIndexCount
568 			DE_NULL,												// const uint32_t*			pQueueFamilyIndices
569 			VK_IMAGE_LAYOUT_UNDEFINED								// VkImageLayout			initialLayout
570 		};
571 
572 		depthImage = createImage(vk, device, &depthImageCreateInfo, DE_NULL);
573 		depthImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *depthImage), MemoryRequirement::Any);
574 		VK_CHECK(vk.bindImageMemory(device, *depthImage, depthImageAllocation->getMemory(), depthImageAllocation->getOffset()));
575 
576 		const VkImageViewCreateInfo imageViewParams =
577 		{
578 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// VkStructureType			sType;
579 			DE_NULL,										// const void*				pNext;
580 			(VkImageViewCreateFlags)0,						// VkImageViewCreateFlags	flags;
581 			*depthImage,									// VkImage					image;
582 			VK_IMAGE_VIEW_TYPE_2D,							// VkImageViewType			viewType;
583 			m_format,										// VkFormat					format;
584 			makeComponentMappingRGBA(),						// VkComponentMapping		components;
585 			depthSubresourceRange,							// VkImageSubresourceRange	subresourceRange;
586 		};
587 		depthImageView = createImageView(vk, device, &imageViewParams);
588 
589 		const VkSamplerCreateInfo depthSamplerCreateInfo =
590 		{
591 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,			// VkStructureType			sType
592 			DE_NULL,										// const void*				pNext
593 			(VkSamplerCreateFlags)0,						// VkSamplerCreateFlags		flags
594 			VK_FILTER_NEAREST,								// VkFilter					minFilter
595 			VK_FILTER_NEAREST,								// VkFilter					magFilter
596 			VK_SAMPLER_MIPMAP_MODE_NEAREST,					// VkSamplerMipMapMode		mipMapMode
597 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode		addressModeU
598 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode		addressModeV
599 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,			// VkSamplerAddressMode		addressmodeW
600 			0.0f,											// float					mipLodBias
601 			VK_FALSE,										// VkBool32					anisotropyEnable
602 			0.0f,											// float					maxAnisotropy
603 			VK_FALSE,										// VkBool32					compareEnable
604 			VK_COMPARE_OP_NEVER,							// VkCompareOp				compareOp
605 			0.0f,											// float					minLod
606 			0.0f,											// float					maxLod
607 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,		// VkBorderColor			borderColor
608 			VK_FALSE										// VkBool32					unnormalizedCoordinates
609 		};
610 
611 		depthSampler = createSampler(vk, device, &depthSamplerCreateInfo, DE_NULL);
612 	}
613 
614 	// Command Pool
615 	{
616 		const VkCommandPoolCreateInfo cmdPoolCreateInfo =
617 		{
618 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType
619 			DE_NULL,											// const void*				pNext
620 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags
621 			queueFamilyIndex									// uint32_t					queueFamilyIndex
622 		};
623 
624 		cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
625 	}
626 
627 	// Command buffer for data transfers
628 	{
629 		const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
630 		{
631 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType		sType,
632 			DE_NULL,										// const void*			pNext
633 			*cmdPool,										// VkCommandPool		commandPool
634 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel	level
635 			1u												// uint32_t				bufferCount
636 		};
637 
638 		transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
639 	}
640 
641 	// Initialize Marker Buffer
642 	{
643 		const VkImageMemoryBarrier imageBarrier[] =
644 		{
645 			{
646 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType		sType
647 				DE_NULL,										// const void*			pNext
648 				0,												// VkAccessMask			srcAccessMask
649 				VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessMask			dstAccessMask
650 				VK_IMAGE_LAYOUT_UNDEFINED,						// VkImageLayout		oldLayout
651 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout		newLayout
652 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t				srcQueueFamilyIndex
653 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t				dstQueueFamilyIndex
654 				*markerImage,									// VkImage				image
655 				{
656 					VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask
657 					0u,										// uint32_t				baseMipLevel
658 					1u,										// uint32_t				mipLevels
659 					0u,										// uint32_t				baseArray
660 					1u										// uint32_t				arraySize
661 				}
662 			},
663 		};
664 
665 		const VkImageMemoryBarrier imagePostBarrier[] =
666 		{
667 			{
668 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// VkStructureType		sType
669 				DE_NULL,										// const void*			pNext
670 				VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlagBits		srcAccessMask
671 				VK_ACCESS_SHADER_WRITE_BIT,						// VkAccessFlagBits		dstAccessMask
672 				VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,			// VkImageLayout		oldLayout
673 				VK_IMAGE_LAYOUT_GENERAL,						// VkImageLayout		newLayout
674 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t				srcQueueFamilyIndex
675 				VK_QUEUE_FAMILY_IGNORED,						// uint32_t				dstQueueFamilyIndex
676 				*markerImage,									// VkImage				image
677 				{
678 					VK_IMAGE_ASPECT_COLOR_BIT,				// VkImageAspectFlags	aspectMask
679 					0u,										// uint32_t				baseMipLevel
680 					1u,										// uint32_t				mipLevels
681 					0u,										// uint32_t				baseArray
682 					1u										// uint32_t				arraySize
683 				}
684 			},
685 		};
686 
687 		beginCommandBuffer(vk, *transferCmdBuffer);
688 		vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
689 				(VkDependencyFlags)0,
690 				0, (const VkMemoryBarrier*)DE_NULL,
691 				0, (const VkBufferMemoryBarrier*)DE_NULL,
692 				DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
693 
694 		const VkClearValue				colorClearValue	= makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 0.0f));
695 		const VkImageSubresourceRange	colorClearRange	= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
696 
697 		vk.cmdClearColorImage(*transferCmdBuffer, *markerImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colorClearValue.color, 1u, &colorClearRange);
698 
699 		vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
700 				(VkDependencyFlags)0,
701 				0, (const VkMemoryBarrier*)DE_NULL,
702 				0, (const VkBufferMemoryBarrier*)DE_NULL,
703 				DE_LENGTH_OF_ARRAY(imagePostBarrier), imagePostBarrier);
704 
705 		endCommandBuffer(vk, *transferCmdBuffer);
706 
707 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
708 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
709 	}
710 
711 
712 	// Perform Draw
713 	{
714 		std::vector<Vec4>				vertices;
715 		std::vector<VulkanShader>		shaders;
716 		Move<VkDescriptorSetLayout>		descriptorSetLayout;
717 		Move<VkDescriptorPool>			descriptorPool;
718 		Move<VkDescriptorSet>			descriptorSet;
719 
720 		// Descriptors
721 		{
722 			DescriptorSetLayoutBuilder	layoutBuilder;
723 			layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
724 			layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
725 			descriptorSetLayout = layoutBuilder.build(vk, device);
726 			descriptorPool = DescriptorPoolBuilder()
727 					.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER)
728 					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
729 					.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
730 
731 			const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
732 			{
733 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
734 				DE_NULL,
735 				*descriptorPool,
736 				1u,
737 				&descriptorSetLayout.get()
738 			};
739 
740 			descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
741 
742 			const VkDescriptorBufferInfo bufferInfo =
743 			{
744 				*controlBuffer,
745 				0u,
746 				VK_WHOLE_SIZE
747 			};
748 
749 			const VkDescriptorImageInfo imageInfo =
750 			{
751 				(VkSampler)DE_NULL,
752 				*markerImageView,
753 				VK_IMAGE_LAYOUT_GENERAL
754 			};
755 
756 			DescriptorSetUpdateBuilder()
757 				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo)
758 				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
759 				.update(vk, device);
760 		}
761 
762 		vertices.push_back(Vec4( -0.70f,	0.5f,	0.0f,	1.0f));
763 		vertices.push_back(Vec4(  0.45f,	-0.75f,	0.0f,	1.0f));
764 		vertices.push_back(Vec4(  0.78f,	0.0f,	0.0f,	1.0f));
765 		vertices.push_back(Vec4( -0.1f,		0.6f,	0.0f,	1.0f));
766 
767 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVert")));
768 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFrag")));
769 
770 		FrameBufferState			frameBufferState(m_renderSize.x(), m_renderSize.y());
771 		PipelineState				pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
772 		DrawCallData				drawCallData(m_topology, vertices);
773 		VulkanProgram				vulkanProgram(shaders);
774 
775 		frameBufferState.depthFormat		= m_format;
776 		frameBufferState.numSamples			= m_samples;
777 		frameBufferState.depthImageView		= *depthImageView;
778 		pipelineState.depthClampEnable		= m_depthClampEnable;
779 		pipelineState.compareOp				= rr::TESTFUNC_ALWAYS;
780 		pipelineState.depthTestEnable		= true;
781 		pipelineState.depthWriteEnable		= true;
782 		pipelineState.sampleShadingEnable	= true;
783 		vulkanProgram.descriptorSetLayout	= *descriptorSetLayout;
784 		vulkanProgram.descriptorSet			= *descriptorSet;
785 
786 		VulkanDrawContext			vulkanDrawContext(m_context, frameBufferState);
787 		vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
788 		vulkanDrawContext.draw();
789 
790 		log << TestLog::Image(	"resultColor",
791 								"Result Color Buffer",
792 								tcu::ConstPixelBufferAccess(tcu::TextureFormat(
793 										vulkanDrawContext.getColorPixels().getFormat()),
794 										vulkanDrawContext.getColorPixels().getWidth(),
795 										vulkanDrawContext.getColorPixels().getHeight(),
796 										1,
797 										vulkanDrawContext.getColorPixels().getDataPtr()));
798 	}
799 
800 	// Barrier to transition between first and second pass
801 	{
802 		const VkImageMemoryBarrier imageBarrier[] =
803 		{
804 			{
805 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType		sType
806 				DE_NULL,													// const void*			pNext
807 				VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,				// VkAccessFlags		srcAccessMask
808 				VK_ACCESS_SHADER_READ_BIT,									// VkAccessFlags		dstAccessMask
809 				VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,			// VkImageLayout		oldLayout
810 				VK_IMAGE_LAYOUT_GENERAL,									// VkImageLayout		newLayout
811 				0u,															// deUint32				srcQueueFamilyIndex
812 				0u,															// deUint32				dstQueueFamilyIndex
813 				*depthImage,												// VkImage				image
814 				{
815 					VK_IMAGE_ASPECT_DEPTH_BIT,						// VkImageAspectFlags		aspectMask
816 					0u,												// deUint32					baseMipLevel
817 					1u,												// deUint32					levelCount
818 					0u,												// deUint32					baseArrayLayer
819 					1u												// deUint32					layerCount
820 				}
821 			},
822 			{
823 				VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,						// VkStructureType		sType
824 				DE_NULL,													// const void*			pNext
825 				0u,															// VkAccessFlags		srcAccessMask
826 				VK_ACCESS_HOST_READ_BIT,									// VkAccessFlags		dstAccessMask
827 				VK_IMAGE_LAYOUT_UNDEFINED,									// VkImageLayout		oldLayout
828 				VK_IMAGE_LAYOUT_GENERAL,									// VkImageLayout		newLayout
829 				0u,															// deUint32				srcQueueFamilyIndex
830 				0u,															// deUint32				dstQueueFamilyIndex
831 				*depthResolveImage,											// VkImage				image
832 				{
833 					VK_IMAGE_ASPECT_COLOR_BIT,						// VkImageAspectFlags		aspectMask
834 					0u,												// deUint32					baseMipLevel
835 					1u,												// deUint32					levelCount
836 					0u,												// deUint32					baseArrayLayer
837 					1u,												// deUint32					layerCount
838 
839 				}
840 			}
841 		};
842 
843 		beginCommandBuffer(vk, *transferCmdBuffer);
844 		vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT | VK_PIPELINE_STAGE_HOST_BIT,
845 				(VkDependencyFlags)0,
846 				0, (const VkMemoryBarrier*)DE_NULL,
847 				0, (const VkBufferMemoryBarrier*)DE_NULL,
848 				DE_LENGTH_OF_ARRAY(imageBarrier), imageBarrier);
849 		endCommandBuffer(vk, *transferCmdBuffer);
850 
851 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
852 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
853 	}
854 
855 	// Resolve Depth Buffer
856 	{
857 		std::vector<Vec4>				vertices;
858 		std::vector<VulkanShader>		shaders;
859 		Move<VkDescriptorSetLayout>		descriptorSetLayout;
860 		Move<VkDescriptorPool>			descriptorPool;
861 		Move<VkDescriptorSet>			descriptorSet;
862 
863 		// Descriptors
864 		{
865 			DescriptorSetLayoutBuilder	layoutBuilder;
866 			layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
867 			layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
868 			descriptorSetLayout = layoutBuilder.build(vk, device);
869 			descriptorPool = DescriptorPoolBuilder()
870 					.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
871 					.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
872 					.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
873 
874 			const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
875 			{
876 				VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
877 				DE_NULL,
878 				*descriptorPool,
879 				1u,
880 				&descriptorSetLayout.get()
881 			};
882 
883 			descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
884 
885 			const VkDescriptorImageInfo depthImageInfo =
886 			{
887 				*depthSampler,
888 				*depthImageView,
889 				VK_IMAGE_LAYOUT_GENERAL
890 			};
891 
892 			const VkDescriptorImageInfo imageInfo =
893 			{
894 				(VkSampler)DE_NULL,
895 				*depthResolveImageView,
896 				VK_IMAGE_LAYOUT_GENERAL
897 			};
898 
899 			DescriptorSetUpdateBuilder()
900 				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &depthImageInfo)
901 				.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
902 				.update(vk, device);
903 		}
904 
905 		vertices.push_back(Vec4( -1.0f,	-1.0f,	0.0f,	1.0f));
906 		vertices.push_back(Vec4( -1.0f,	 1.0f,	0.0f,	1.0f));
907 		vertices.push_back(Vec4(  1.0f,	-1.0f,	0.0f,	1.0f));
908 		vertices.push_back(Vec4(  1.0f,	 1.0f,	0.0f,	1.0f));
909 
910 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragDepthVertPass2")));
911 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragDepthFragPass2")));
912 
913 		FrameBufferState			frameBufferState(m_renderSize.x(), m_renderSize.y());
914 		PipelineState				pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
915 		DrawCallData				drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
916 		VulkanProgram				vulkanProgram(shaders);
917 
918 		frameBufferState.numSamples				= m_samples;
919 		pipelineState.sampleShadingEnable		= true;
920 		vulkanProgram.descriptorSetLayout		= *descriptorSetLayout;
921 		vulkanProgram.descriptorSet				= *descriptorSet;
922 
923 		VulkanDrawContext		vulkanDrawContext(m_context, frameBufferState);
924 		vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
925 		vulkanDrawContext.draw();
926 	}
927 
928 	// Transfer marker buffer
929 	{
930 		beginCommandBuffer(vk, *transferCmdBuffer);
931 		copyImageToBuffer(vk, *transferCmdBuffer, *markerImage, *markerBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
932 		endCommandBuffer(vk, *transferCmdBuffer);
933 
934 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
935 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
936 	}
937 
938 	// Verify depth buffer
939 	{
940 		bool status;
941 
942 		beginCommandBuffer(vk, *transferCmdBuffer, 0u);
943 		copyImageToBuffer(vk, *transferCmdBuffer, *depthResolveImage, *validationBuffer, tcu::IVec2(m_renderSize.x() * m_samples, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
944 		endCommandBuffer(vk, *transferCmdBuffer);
945 
946 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
947 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
948 
949 		invalidateMappedMemoryRange(vk, device, validationAlloc->getMemory(), validationAlloc->getOffset(), VK_WHOLE_SIZE);
950 		invalidateMappedMemoryRange(vk, device, markerBufferAllocation->getMemory(), markerBufferAllocation->getOffset(), VK_WHOLE_SIZE);
951 
952 		tcu::ConstPixelBufferAccess resultPixelBuffer(mapVkFormat(VK_FORMAT_R32_SFLOAT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, validationAlloc->getHostPtr());
953 		tcu::ConstPixelBufferAccess markerPixelBuffer(mapVkFormat(VK_FORMAT_R8G8B8A8_UINT), m_renderSize.x() * m_samples, m_renderSize.y(), 1u, markerBufferAllocation->getHostPtr());
954 		status = validateDepthBuffer(resultPixelBuffer, markerPixelBuffer, 0.001f);
955 		testDesc = "gl_FragDepth " + getPrimitiveTopologyShortName(m_topology) + " ";
956 		if (status)
957 		{
958 			testDesc += "passed";
959 			return tcu::TestStatus::pass(testDesc.c_str());
960 		}
961 		else
962 		{
963 			log << TestLog::Image("resultDepth", "Result Depth Buffer", resultPixelBuffer);
964 			testDesc += "failed";
965 			return tcu::TestStatus::fail(testDesc.c_str());
966 		}
967 	}
968 }
969 
validateDepthBuffer(const tcu::ConstPixelBufferAccess & validationBuffer,const tcu::ConstPixelBufferAccess & markerBuffer,const float tolerance) const970 bool BuiltinFragDepthCaseInstance::validateDepthBuffer (const tcu::ConstPixelBufferAccess& validationBuffer, const tcu::ConstPixelBufferAccess& markerBuffer, const float tolerance) const
971 {
972 	TestLog& log = m_context.getTestContext().getLog();
973 
974 	for (deUint32 rowNdx = 0; rowNdx < m_renderSize.y(); rowNdx++)
975 	{
976 		for (deUint32 colNdx = 0; colNdx < m_renderSize.x(); colNdx++)
977 		{
978 			const float multiplier		= m_depthClampEnable ? 0.0f : 1.0f;
979 			float expectedValue	= (float)(rowNdx * m_renderSize.x() + colNdx)/256.0f * multiplier;
980 
981 			if (m_largeDepthEnable)
982 				expectedValue += m_largeDepthBase;
983 
984 			for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_samples; sampleNdx++)
985 			{
986 				const float	actualValue		= validationBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
987 				const float	markerValue		= markerBuffer.getPixel(sampleNdx + m_samples * colNdx, rowNdx).x();
988 
989 				if (markerValue != 0)
990 				{
991 					if (de::abs(expectedValue - actualValue) > tolerance)
992 					{
993 						log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
994 						return false;
995 					}
996 				}
997 				else
998 				{
999 					if (de::abs(actualValue - m_defaultDepthValue) > tolerance)
1000 					{
1001 						log << TestLog::Message << "Mismatch at pixel (" << colNdx << "," << rowNdx << "," << sampleNdx << "): expected " << expectedValue << " but got " << actualValue << TestLog::EndMessage;
1002 						return false;
1003 					}
1004 				}
1005 			}
1006 		}
1007 	}
1008 
1009 	return true;
1010 }
1011 
1012 class BuiltinFragCoordMsaaCaseInstance : public TestInstance
1013 {
1014 public:
1015 	enum
1016 	{
1017 		RENDERWIDTH		= 16,
1018 		RENDERHEIGHT	= 16
1019 	};
1020 				BuiltinFragCoordMsaaCaseInstance	(Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable);
1021 	TestStatus	iterate								(void);
1022 private:
1023 	bool		validateSampleLocations				(const ConstPixelBufferAccess& sampleLocationBuffer) const;
1024 
1025 	const tcu::UVec2				m_renderSize;
1026 	const VkSampleCountFlagBits		m_sampleCount;
1027 	const bool						m_sampleShading;
1028 	const std::vector<uint32_t>		m_sampleMaskArray;
1029 	const bool						m_useEnable;
1030 };
1031 
BuiltinFragCoordMsaaCaseInstance(Context & context,VkSampleCountFlagBits sampleCount,bool sampleShading,std::vector<uint32_t> sampleMaskArray,bool useEnable)1032 BuiltinFragCoordMsaaCaseInstance::BuiltinFragCoordMsaaCaseInstance (Context& context, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useEnable)
1033 	: TestInstance		(context)
1034 	, m_renderSize		(RENDERWIDTH, RENDERHEIGHT)
1035 	, m_sampleCount		(sampleCount)
1036 	, m_sampleShading	(sampleShading)
1037 	, m_sampleMaskArray	(sampleMaskArray)
1038 	, m_useEnable		(useEnable)
1039 {
1040 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
1041 	const VkPhysicalDevice		physicalDevice		= m_context.getPhysicalDevice();
1042 
1043 	if (!context.getDeviceFeatures().sampleRateShading)
1044 		TCU_THROW(NotSupportedError, "sampleRateShading not supported");
1045 
1046 	try
1047 	{
1048 		VkImageFormatProperties		imageFormatProperties;
1049 		VkFormatProperties			formatProperties;
1050 
1051 		if (m_context.getDeviceFeatures().fragmentStoresAndAtomics == VK_FALSE)
1052 			throw tcu::NotSupportedError("fragmentStoresAndAtomics not supported");
1053 
1054 		if (m_context.getDeviceFeatures().sampleRateShading == VK_FALSE)
1055 			throw tcu::NotSupportedError("sampleRateShading not supported");
1056 
1057 		imageFormatProperties = getPhysicalDeviceImageFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT, VK_IMAGE_TYPE_2D,
1058 				VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, (VkImageCreateFlags)0);
1059 
1060 		if ((imageFormatProperties.sampleCounts & m_sampleCount) == 0)
1061 			throw tcu::NotSupportedError("Image format and sample count not supported");
1062 
1063 		formatProperties = getPhysicalDeviceFormatProperties(vki, physicalDevice, VK_FORMAT_R32G32B32A32_SFLOAT);
1064 
1065 		if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
1066 			throw tcu::NotSupportedError("Output format not supported as storage image");
1067 	}
1068 	catch (const vk::Error& e)
1069 	{
1070 		if (e.getError() == VK_ERROR_FORMAT_NOT_SUPPORTED)
1071 			throw tcu::NotSupportedError("Image format not supported");
1072 		else
1073 			throw;
1074 
1075 	}
1076 }
1077 
iterate(void)1078 TestStatus BuiltinFragCoordMsaaCaseInstance::iterate (void)
1079 {
1080 	const VkDevice					device				= m_context.getDevice();
1081 	const DeviceInterface&			vk					= m_context.getDeviceInterface();
1082 	const VkQueue					queue				= m_context.getUniversalQueue();
1083 	Allocator&						allocator			= m_context.getDefaultAllocator();
1084 	const deUint32					queueFamilyIndex	= m_context.getUniversalQueueFamilyIndex();
1085 	TestLog&						log					= m_context.getTestContext().getLog();
1086 	Move<VkImage>					outputImage;
1087 	Move<VkImageView>				outputImageView;
1088 	MovePtr<Allocation>				outputImageAllocation;
1089 	Move<VkDescriptorSetLayout>		descriptorSetLayout;
1090 	Move<VkDescriptorPool>			descriptorPool;
1091 	Move<VkDescriptorSet>			descriptorSet;
1092 	Move<VkBuffer>					sampleLocationBuffer;
1093 	MovePtr<Allocation>				sampleLocationBufferAllocation;
1094 	Move<VkCommandPool>				cmdPool;
1095 	Move<VkCommandBuffer>			transferCmdBuffer;
1096 
1097 	// Coordinate result image
1098 	{
1099 		const VkImageCreateInfo outputImageCreateInfo =
1100 		{
1101 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,					// VkStructureType			sType
1102 			DE_NULL,												// const void*				pNext
1103 			(VkImageCreateFlags)0,									// VkImageCreateFlags		flags
1104 			VK_IMAGE_TYPE_2D,										// VkImageType				imageType
1105 			VK_FORMAT_R32G32B32A32_SFLOAT,							// VkFormat					format
1106 			makeExtent3D(m_sampleCount * m_renderSize.x(), m_renderSize.y(), 1u),	// VkExtent3D				extent3d
1107 			1u,														// uint32_t					mipLevels
1108 			1u,														// uint32_t					arrayLayers
1109 			VK_SAMPLE_COUNT_1_BIT,									// VkSampleCountFlagBits	samples
1110 			VK_IMAGE_TILING_OPTIMAL,								// VkImageTiling			tiling
1111 			VK_IMAGE_USAGE_STORAGE_BIT |							// VkImageUsageFlags		usage
1112 			VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1113 			VK_SHARING_MODE_EXCLUSIVE,								// VkSharingMode			sharingMode
1114 			0u,														// uint32_t					queueFamilyIndexCount
1115 			DE_NULL,												// const uint32_t*			pQueueFamilyIndices
1116 			VK_IMAGE_LAYOUT_UNDEFINED								// VkImageLayout			initialLayout
1117 		};
1118 
1119 		outputImage = createImage(vk, device, &outputImageCreateInfo, DE_NULL);
1120 		outputImageAllocation = allocator.allocate(getImageMemoryRequirements(vk, device, *outputImage), MemoryRequirement::Any);
1121 		vk.bindImageMemory(device, *outputImage, outputImageAllocation->getMemory(), outputImageAllocation->getOffset());
1122 
1123 		VkImageSubresourceRange imageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1124 		const VkImageViewCreateInfo outputImageViewCreateInfo =
1125 		{
1126 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,				// VkStructureType			sType
1127 			DE_NULL,												// const void*				pNext
1128 			(VkImageViewCreateFlags)0,								// VkImageViewCreateFlags	flags
1129 			*outputImage,											// VkImage					image
1130 			VK_IMAGE_VIEW_TYPE_2D,									// VkImageViewType			viewType
1131 			VK_FORMAT_R32G32B32A32_SFLOAT,							// VkFormat					format,
1132 			makeComponentMappingRGBA(),								// VkComponentMapping		components
1133 			imageSubresourceRange									// VkImageSubresourceRange	imageSubresourceRange
1134 		};
1135 
1136 		outputImageView = createImageView(vk, device, &outputImageViewCreateInfo);
1137 	}
1138 
1139 	// Validation buffer
1140 	{
1141 		VkDeviceSize  pixelSize = getPixelSize(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT));
1142 		const VkBufferCreateInfo sampleLocationBufferCreateInfo =
1143 		{
1144 			VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,				// VkStructureType		sType
1145 			DE_NULL,											// const void*			pNext
1146 			(VkBufferCreateFlags)0,								// VkBufferCreateFlags	flags
1147 			m_sampleCount * m_renderSize.x() * m_renderSize.y() * pixelSize,	// VkDeviceSize			size
1148 			VK_BUFFER_USAGE_TRANSFER_DST_BIT,					// VkBufferUsageFlags	usage
1149 			VK_SHARING_MODE_EXCLUSIVE,							// VkSharingMode		mode
1150 			0u,													// uint32_t				queueFamilyIndexCount
1151 			DE_NULL												// const uint32_t*		pQueueFamilyIndices
1152 		};
1153 
1154 		sampleLocationBuffer = createBuffer(vk, device, &sampleLocationBufferCreateInfo, DE_NULL);
1155 		sampleLocationBufferAllocation = allocator.allocate(getBufferMemoryRequirements(vk, device, *sampleLocationBuffer), MemoryRequirement::HostVisible);
1156 		vk.bindBufferMemory(device, *sampleLocationBuffer, sampleLocationBufferAllocation->getMemory(), sampleLocationBufferAllocation->getOffset());
1157 	}
1158 
1159 	// Descriptors
1160 	{
1161 		DescriptorSetLayoutBuilder		layoutBuilder;
1162 		layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
1163 		descriptorSetLayout = layoutBuilder.build(vk, device);
1164 		descriptorPool = DescriptorPoolBuilder()
1165 			.addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
1166 			.build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
1167 
1168 		const VkDescriptorSetAllocateInfo descriptorSetAllocInfo =
1169 		{
1170 			VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1171 			DE_NULL,
1172 			*descriptorPool,
1173 			1u,
1174 			&*descriptorSetLayout
1175 		};
1176 
1177 		descriptorSet = allocateDescriptorSet(vk, device, &descriptorSetAllocInfo);
1178 
1179 		const VkDescriptorImageInfo imageInfo =
1180 		{
1181 			(VkSampler)DE_NULL,
1182 			*outputImageView,
1183 			VK_IMAGE_LAYOUT_GENERAL
1184 		};
1185 
1186 		DescriptorSetUpdateBuilder()
1187 			.writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &imageInfo)
1188 			.update(vk, device);
1189 	}
1190 
1191 	// Command Pool
1192 	{
1193 		const VkCommandPoolCreateInfo cmdPoolCreateInfo =
1194 		{
1195 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,			// VkStructureType			sType
1196 			DE_NULL,											// const void*				pNext
1197 			VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,	// VkCommandPoolCreateFlags	flags
1198 			queueFamilyIndex									// uint32_t					queueFamilyIndex
1199 		};
1200 
1201 		cmdPool = createCommandPool(vk, device, &cmdPoolCreateInfo);
1202 	}
1203 
1204 	// Command buffer for data transfers
1205 	{
1206 		const VkCommandBufferAllocateInfo cmdBufferAllocInfo =
1207 		{
1208 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType		sType,
1209 			DE_NULL,										// const void*			pNext
1210 			*cmdPool,										// VkCommandPool		commandPool
1211 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel	level
1212 			1u												// uint32_t				bufferCount
1213 		};
1214 
1215 		transferCmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocInfo);
1216 	}
1217 
1218 	// Transition the output image to LAYOUT_GENERAL
1219 	{
1220 		const VkImageMemoryBarrier barrier =
1221 		{
1222 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType		sType
1223 			DE_NULL,									// const void*			pNext
1224 			0u,											// VkAccessFlags		srcAccessMask
1225 			VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags		dstAccessMask
1226 			VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout		oldLayout
1227 			VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout		newLayout
1228 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t				srcQueueFamilyIndex
1229 			VK_QUEUE_FAMILY_IGNORED,					// uint32_t				dstQueueFamilyIndex
1230 			*outputImage,								// VkImage				image
1231 			{
1232 				VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags	aspectMask
1233 				0u,									// uint32_t				baseMipLevel
1234 				1u,									// uint32_t				mipLevels
1235 				0u,									// uint32_t				baseArray
1236 				1u									// uint32_t				arraySize
1237 			}
1238 		};
1239 
1240 		beginCommandBuffer(vk, *transferCmdBuffer);
1241 		vk.cmdPipelineBarrier(*transferCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
1242 				(VkDependencyFlags)0,
1243 				0, (const VkMemoryBarrier*)DE_NULL,
1244 				0, (const VkBufferMemoryBarrier*)DE_NULL,
1245 				1, &barrier);
1246 
1247 		endCommandBuffer(vk, *transferCmdBuffer);
1248 
1249 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1250 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
1251 	}
1252 
1253 	// Perform draw
1254 	{
1255 		std::vector<Vec4>				vertices;
1256 		std::vector<VulkanShader>		shaders;
1257 
1258 		vertices.push_back(Vec4( -1.0f,	-1.0f,	0.0f,	1.0f));
1259 		vertices.push_back(Vec4( -1.0f,	 1.0f,	0.0f,	1.0f));
1260 		vertices.push_back(Vec4(  1.0f,	-1.0f,	0.0f,	1.0f));
1261 		vertices.push_back(Vec4(  1.0f,	 1.0f,	0.0f,	1.0f));
1262 
1263 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("FragCoordMsaaVert")));
1264 		shaders.push_back(VulkanShader(VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("FragCoordMsaaFrag")));
1265 
1266 		FrameBufferState			frameBufferState(m_renderSize.x(), m_renderSize.y());
1267 		PipelineState				pipelineState(m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1268 		DrawCallData				drawCallData(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, vertices);
1269 		VulkanProgram				vulkanProgram(shaders);
1270 
1271 		frameBufferState.numSamples				= m_sampleCount;
1272 		pipelineState.sampleShadingEnable		= m_useEnable; // When m_useEnable is false, we rely on the gl_SampleID input to enable sample shading
1273 		pipelineState.sampleMasks				= m_sampleMaskArray;
1274 		vulkanProgram.descriptorSetLayout		= *descriptorSetLayout;
1275 		vulkanProgram.descriptorSet				= *descriptorSet;
1276 
1277 		VulkanDrawContext			vulkanDrawContext(m_context, frameBufferState);
1278 		vulkanDrawContext.registerDrawObject(pipelineState, vulkanProgram, drawCallData);
1279 		vulkanDrawContext.draw();
1280 
1281 		log << TestLog::Image(	"result",
1282 								"result",
1283 								tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1284 										vulkanDrawContext.getColorPixels().getFormat()),
1285 										vulkanDrawContext.getColorPixels().getWidth(),
1286 										vulkanDrawContext.getColorPixels().getHeight(),
1287 										1,
1288 										vulkanDrawContext.getColorPixels().getDataPtr()));
1289 	}
1290 
1291 	// Transfer location image to buffer
1292 	{
1293 		beginCommandBuffer(vk, *transferCmdBuffer);
1294 		copyImageToBuffer(vk, *transferCmdBuffer, *outputImage, *sampleLocationBuffer, tcu::IVec2(m_renderSize.x() * m_sampleCount, m_renderSize.y()), VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
1295 		endCommandBuffer(vk, *transferCmdBuffer);
1296 
1297 		submitCommandsAndWait(vk, device, queue, transferCmdBuffer.get());
1298 		m_context.resetCommandPoolForVKSC(device, *cmdPool);
1299 
1300 		invalidateAlloc(vk, device, *sampleLocationBufferAllocation);
1301 	}
1302 
1303 	// Validate result
1304 	{
1305 		bool status;
1306 
1307 		ConstPixelBufferAccess sampleLocationPixelBuffer(mapVkFormat(VK_FORMAT_R32G32B32A32_SFLOAT), m_sampleCount * m_renderSize.x(),
1308 				m_renderSize.y(), 1u, sampleLocationBufferAllocation->getHostPtr());
1309 
1310 		status = validateSampleLocations(sampleLocationPixelBuffer);
1311 		if (status)
1312 			return TestStatus::pass("FragCoordMsaa passed");
1313 		else
1314 			return TestStatus::fail("FragCoordMsaa failed");
1315 	}
1316 }
1317 
pixelOffsetCompare(const Vec2 & a,const Vec2 & b)1318 static bool pixelOffsetCompare (const Vec2& a, const Vec2& b)
1319 {
1320 	return a.x() < b.x();
1321 }
1322 
validateSampleLocations(const ConstPixelBufferAccess & sampleLocationBuffer) const1323 bool BuiltinFragCoordMsaaCaseInstance::validateSampleLocations (const ConstPixelBufferAccess& sampleLocationBuffer) const
1324 {
1325 	const InstanceInterface&	vki					= m_context.getInstanceInterface();
1326 	TestLog&					log					= m_context.getTestContext().getLog();
1327 	const VkPhysicalDevice		physicalDevice		= m_context.getPhysicalDevice();
1328 	deUint32					logSampleCount		= deLog2Floor32(m_sampleCount);
1329 	VkPhysicalDeviceProperties	physicalDeviceProperties;
1330 
1331 	static const Vec2 sampleCount1Bit[] =
1332 	{
1333 		Vec2(0.5f, 0.5f)
1334 	};
1335 
1336 	static const Vec2 sampleCount2Bit[] =
1337 	{
1338 		Vec2(0.25f, 0.25f), Vec2(0.75f, 0.75f)
1339 	};
1340 
1341 	static const Vec2 sampleCount4Bit[] =
1342 	{
1343 		Vec2(0.375f, 0.125f), Vec2(0.875f, 0.375f), Vec2(0.125f, 0.625f), Vec2(0.625f, 0.875f)
1344 	};
1345 
1346 	static const Vec2 sampleCount8Bit[] =
1347 	{
1348 		Vec2(0.5625f, 0.3125f), Vec2(0.4375f, 0.6875f), Vec2(0.8125f,0.5625f), Vec2(0.3125f, 0.1875f),
1349 		Vec2(0.1875f, 0.8125f), Vec2(0.0625f, 0.4375f), Vec2(0.6875f,0.9375f), Vec2(0.9375f, 0.0625f)
1350 	};
1351 
1352 	static const Vec2 sampleCount16Bit[] =
1353 	{
1354 		Vec2(0.5625f, 0.5625f), Vec2(0.4375f, 0.3125f), Vec2(0.3125f,0.6250f), Vec2(0.7500f, 0.4375f),
1355 		Vec2(0.1875f, 0.3750f), Vec2(0.6250f, 0.8125f), Vec2(0.8125f,0.6875f), Vec2(0.6875f, 0.1875f),
1356 		Vec2(0.3750f, 0.8750f), Vec2(0.5000f, 0.0625f), Vec2(0.2500f,0.1250f), Vec2(0.1250f, 0.7500f),
1357 		Vec2(0.0000f, 0.5000f), Vec2(0.9375f, 0.2500f), Vec2(0.8750f,0.9375f), Vec2(0.0625f, 0.0000f)
1358 	};
1359 
1360 	static const Vec2* standardSampleLocationTable[] =
1361 	{
1362 		sampleCount1Bit,
1363 		sampleCount2Bit,
1364 		sampleCount4Bit,
1365 		sampleCount8Bit,
1366 		sampleCount16Bit
1367 	};
1368 
1369 	vki.getPhysicalDeviceProperties(physicalDevice, &physicalDeviceProperties);
1370 
1371 	for (deInt32 rowNdx = 0; rowNdx < (deInt32)m_renderSize.y(); rowNdx++)
1372 	{
1373 		for (deInt32 colNdx = 0; colNdx < (deInt32)m_renderSize.x(); colNdx++)
1374 		{
1375 			// Check standard sample locations
1376 			if (m_sampleShading == true)
1377 			{
1378 				std::vector<Vec2> locations;
1379 
1380 				for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1381 				{
1382 					const UVec2 pixelAddress	= UVec2(sampleNdx + m_sampleCount * colNdx, rowNdx);
1383 					const Vec4  pixelData		= sampleLocationBuffer.getPixel(pixelAddress.x(), pixelAddress.y());
1384 
1385 					if (pixelData.z() != 0.0f)
1386 					{
1387 						log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1388 						return false;
1389 					}
1390 
1391 					if (pixelData.w() != 1.0f)
1392 					{
1393 						log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1394 						return false;
1395 					}
1396 
1397 					locations.push_back(Vec2(pixelData.x(), pixelData.y()));
1398 				}
1399 				std::sort(locations.begin(), locations.end(), pixelOffsetCompare);
1400 				for (std::vector<Vec2>::const_iterator sampleIt = locations.begin(); sampleIt != locations.end(); sampleIt++)
1401 				{
1402 					IVec2	sampleFloor(deFloorFloatToInt32((*sampleIt).x()), deFloorFloatToInt32((*sampleIt).y()));
1403 					IVec2	sampleCeil(deCeilFloatToInt32((*sampleIt).x()), deCeilFloatToInt32((*sampleIt).y()));
1404 
1405 					if ((sampleFloor.x() < colNdx) || (sampleCeil.x() > colNdx + 1) || (sampleFloor.y() < rowNdx) || (sampleCeil.y() > rowNdx + 1))
1406 					{
1407 						log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): " << *sampleIt << TestLog::EndMessage;
1408 						return false;
1409 					}
1410 				}
1411 
1412 				std::vector<Vec2>::iterator last = std::unique(locations.begin(), locations.end());
1413 				if (last != locations.end())
1414 				{
1415 					log << TestLog::Message << "Fail: Sample locations contains non-unique entry" << TestLog::EndMessage;
1416 					return false;
1417 				}
1418 
1419 				if (logSampleCount < DE_LENGTH_OF_ARRAY(standardSampleLocationTable))
1420 				{
1421 					if (physicalDeviceProperties.limits.standardSampleLocations)
1422 					{
1423 						for (deUint32 sampleNdx = 0; sampleNdx < (deUint32)m_sampleCount; sampleNdx++)
1424 						{
1425 							if (!de::contains(locations.begin(), locations.end(), standardSampleLocationTable[logSampleCount][sampleNdx] + Vec2(float(colNdx), float(rowNdx))))
1426 							{
1427 								log << TestLog::Message << "Didn't match sample locations " << standardSampleLocationTable[logSampleCount][sampleNdx] << TestLog::EndMessage;
1428 								return false;
1429 							}
1430 						}
1431 					}
1432 				}
1433 			}
1434 			else
1435 			{
1436 				// Check the sample location is at the pixel center when sample shading is disabled.
1437 				const Vec4 pixelData = sampleLocationBuffer.getPixel(colNdx, rowNdx);
1438 
1439 				if (pixelData.z() != 0.0f)
1440 				{
1441 					log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .z component, expected: 0.0, got: " << pixelData.z() << TestLog::EndMessage;
1442 					return false;
1443 				}
1444 
1445 				if (pixelData.w() != 1.0f)
1446 				{
1447 					log << TestLog::Message << "Pixel (" << colNdx << "," << rowNdx << "): has unexpected .w component, expected: 1.0, got: " << pixelData.w() << TestLog::EndMessage;
1448 					return false;
1449 				}
1450 
1451 				if (!(deFloatFrac(pixelData.x()) == 0.5f && deFloatFrac(pixelData.y()) == 0.5f))
1452 				{
1453 					log << TestLog::Message << "Didn't match sample locations (" << pixelData.x() << ", " << pixelData.y() << "): " << Vec2(float(colNdx) + 0.5f, float(rowNdx) + 0.5f) << TestLog::EndMessage;
1454 					return false;
1455 				}
1456 			}
1457 		}
1458 	}
1459 
1460 	return true;
1461 }
1462 
1463 class BuiltinFragCoordMsaaTestCase : public TestCase
1464 {
1465 public:
1466 					BuiltinFragCoordMsaaTestCase	(TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable);
1467 	virtual			~BuiltinFragCoordMsaaTestCase	(void);
1468 	void			initPrograms					(SourceCollections& sourceCollections) const;
1469 	TestInstance*	createInstance					(Context& context) const;
1470 private:
1471 	const VkSampleCountFlagBits		m_sampleCount;
1472 	const bool						m_sampleShading;	// Enable or disable Sample Shading.
1473 	const std::vector<uint32_t>		m_sampleMaskArray;
1474 	const bool						m_useCentroid;		// Use Centroid interpolation decoration.
1475 	const bool						m_useEnable;
1476 };
1477 
BuiltinFragCoordMsaaTestCase(TestContext & testCtx,const char * name,const char * description,VkSampleCountFlagBits sampleCount,bool sampleShading,std::vector<uint32_t> sampleMaskArray,bool useCentroid,bool useEnable)1478 BuiltinFragCoordMsaaTestCase::BuiltinFragCoordMsaaTestCase (TestContext& testCtx, const char* name, const char* description, VkSampleCountFlagBits sampleCount, bool sampleShading, std::vector<uint32_t> sampleMaskArray, bool useCentroid, bool useEnable)
1479 	: TestCase			(testCtx, name, description)
1480 	, m_sampleCount		(sampleCount)
1481 	, m_sampleShading	(sampleShading)
1482 	, m_sampleMaskArray	(sampleMaskArray)
1483 	, m_useCentroid		(useCentroid)
1484 	, m_useEnable		(useEnable)
1485 {
1486 }
1487 
~BuiltinFragCoordMsaaTestCase(void)1488 BuiltinFragCoordMsaaTestCase::~BuiltinFragCoordMsaaTestCase (void)
1489 {
1490 }
1491 
initPrograms(SourceCollections & programCollection) const1492 void BuiltinFragCoordMsaaTestCase::initPrograms (SourceCollections& programCollection) const
1493 {
1494 	{
1495 		std::ostringstream vertexSource;
1496 		vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1497 			<< "\n"
1498 			<< "layout (location = 0) in vec4 position;\n"
1499 			<< "void main()\n"
1500 			<< "{\n"
1501 			<< "	gl_Position = position;\n"
1502 			<< "}\n";
1503 		programCollection.glslSources.add("FragCoordMsaaVert") << glu::VertexSource(vertexSource.str());
1504 	}
1505 
1506 	if(m_sampleShading == true)
1507 	{
1508 		std::ostringstream fragmentSource;
1509 		fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1510 			<< "\n"
1511 			<< "layout(location = 0) out mediump vec4 color;\n"
1512 			<< "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1513 			<< "void main()\n"
1514 			<< "{\n"
1515 			<< "	const int sampleNdx = int(gl_SampleID);\n"
1516 			<< "	ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_sampleCount << ", int(gl_FragCoord.y));\n"
1517 			<< "	imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1518 			<< "	color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1519 			<< "}\n";
1520 		programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(fragmentSource.str());
1521 	}
1522 	else
1523 	{
1524 		if (m_useCentroid == false)
1525 		{
1526 			std::ostringstream src;
1527 
1528 			src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1529 				<< "\n"
1530 				<< "layout (location = 0) out mediump vec4 color;\n"
1531 				<< "layout (set = 0, binding = 0, rgba32f) writeonly uniform image2D storageImage;\n"
1532 				<< "void main()\n"
1533 				<< "{\n"
1534 				<< "	ivec2 imageCoord = ivec2(int(gl_FragCoord.x), int(gl_FragCoord.y));\n"
1535 				<< "	imageStore(storageImage, imageCoord, gl_FragCoord);\n"
1536 				<< "	color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1537 				<< "}\n";
1538 
1539 			programCollection.glslSources.add("FragCoordMsaaFrag") << glu::FragmentSource(src.str());
1540 		}
1541 		else
1542 		{
1543 			// This SPIR-V shader is identical to GLSL shader above but with the exception of that added cendroid decoration line.
1544 			std::ostringstream src;
1545 			src << "; SPIR - V\n"
1546 				<< "; Version: 1.0\n"
1547 				<< "; Generator: Khronos Glslang Reference Front End; 10\n"
1548 				<< "; Bound: 36\n"
1549 				<< "; Schema: 0\n"
1550 				<< "OpCapability Shader\n"
1551 				<< "%1 = OpExtInstImport \"GLSL.std.450\"\n"
1552 				<< "OpMemoryModel Logical GLSL450\n"
1553 				<< "OpEntryPoint Fragment %main \"main\" %gl_FragCoord %color\n"
1554 				<< "OpExecutionMode %main OriginUpperLeft\n"
1555 				<< "OpSource GLSL 450\n"
1556 				<< "OpName %main \"main\"\n"
1557 				<< "OpName %imageCoord \"imageCoord\"\n"
1558 				<< "OpName %gl_FragCoord \"gl_FragCoord\"\n"
1559 				<< "OpName %storageImage \"storageImage\"\n"
1560 				<< "OpName %color \"color\"\n"
1561 				<< "OpDecorate %gl_FragCoord BuiltIn FragCoord\n"
1562 				<< "OpDecorate %gl_FragCoord Centroid\n"
1563 				<< "OpDecorate %storageImage DescriptorSet 0\n"
1564 				<< "OpDecorate %storageImage Binding 0\n"
1565 				<< "OpDecorate %storageImage NonReadable\n"
1566 				<< "OpDecorate %color RelaxedPrecision\n"
1567 				<< "OpDecorate %color Location 0\n"
1568 				<< "%void = OpTypeVoid\n"
1569 				<< "%3 = OpTypeFunction %void\n"
1570 				<< "%int = OpTypeInt 32 1\n"
1571 				<< "%v2int = OpTypeVector %int 2\n"
1572 				<< "%_ptr_Function_v2int = OpTypePointer Function %v2int\n"
1573 				<< "%float = OpTypeFloat 32\n"
1574 				<< "%v4float = OpTypeVector %float 4\n"
1575 				<< "%_ptr_Input_v4float = OpTypePointer Input %v4float\n"
1576 				<< "%gl_FragCoord = OpVariable %_ptr_Input_v4float Input\n"
1577 				<< "%uint = OpTypeInt 32 0\n"
1578 				<< "%uint_0 = OpConstant %uint 0\n"
1579 				<< "%_ptr_Input_float = OpTypePointer Input %float\n"
1580 				<< "%uint_1 = OpConstant %uint 1\n"
1581 				<< "%25 = OpTypeImage %float 2D 0 0 0 2 Rgba32f\n"
1582 				<< "%_ptr_UniformConstant_25 = OpTypePointer UniformConstant %25\n"
1583 				<< "%storageImage = OpVariable %_ptr_UniformConstant_25 UniformConstant\n"
1584 				<< "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
1585 				<< "%color = OpVariable %_ptr_Output_v4float Output\n"
1586 				<< "%float_1 = OpConstant %float 1\n"
1587 				<< "%float_0 = OpConstant %float 0\n"
1588 				<< "%35 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1\n"
1589 				<< "%main = OpFunction %void None %3\n"
1590 				<< "%5 = OpLabel\n"
1591 				<< "%imageCoord = OpVariable %_ptr_Function_v2int Function\n"
1592 				<< "%17 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_0\n"
1593 				<< "%18 = OpLoad %float %17\n"
1594 				<< "%19 = OpConvertFToS %int %18\n"
1595 				<< "%21 = OpAccessChain %_ptr_Input_float %gl_FragCoord %uint_1\n"
1596 				<< "%22 = OpLoad %float %21\n"
1597 				<< "%23 = OpConvertFToS %int %22\n"
1598 				<< "%24 = OpCompositeConstruct %v2int %19 %23\n"
1599 				<< "OpStore %imageCoord %24\n"
1600 				<< "%28 = OpLoad %25 %storageImage\n"
1601 				<< "%29 = OpLoad %v2int %imageCoord\n"
1602 				<< "%30 = OpLoad %v4float %gl_FragCoord\n"
1603 				<< "OpImageWrite %28 %29 %30\n"
1604 				<< "OpStore %color %35\n"
1605 				<< "OpReturn\n"
1606 				<< "OpFunctionEnd\n";
1607 
1608 			programCollection.spirvAsmSources.add("FragCoordMsaaFrag") << src.str();
1609 		}
1610 	}
1611 }
1612 
createInstance(Context & context) const1613 TestInstance* BuiltinFragCoordMsaaTestCase::createInstance (Context& context) const
1614 {
1615 	return new BuiltinFragCoordMsaaCaseInstance(context, m_sampleCount, m_sampleShading, m_sampleMaskArray, m_useEnable);
1616 }
1617 
1618 class BuiltinFragDepthCase : public TestCase
1619 {
1620 public:
1621 					BuiltinFragDepthCase		(TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology,  VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits samples);
1622 	virtual			~BuiltinFragDepthCase		(void);
1623 
1624 	void			initPrograms				(SourceCollections& dst) const;
1625 	TestInstance*	createInstance				(Context& context) const;
1626 
1627 private:
1628 	const VkPrimitiveTopology		m_topology;
1629 	const VkFormat					m_format;
1630 	const bool						m_largeDepthEnable;
1631 	const float						m_defaultDepth;
1632 	const bool						m_depthClampEnable;
1633 	const VkSampleCountFlagBits		m_samples;
1634 };
1635 
BuiltinFragDepthCase(TestContext & testCtx,const char * name,const char * description,VkPrimitiveTopology topology,VkFormat format,bool largeDepthEnable,bool depthClampEnable,const VkSampleCountFlagBits samples)1636 BuiltinFragDepthCase::BuiltinFragDepthCase (TestContext& testCtx, const char* name, const char* description, VkPrimitiveTopology topology, VkFormat format, bool largeDepthEnable, bool depthClampEnable, const VkSampleCountFlagBits  samples)
1637 	: TestCase				(testCtx, name, description)
1638 	, m_topology			(topology)
1639 	, m_format				(format)
1640 	, m_largeDepthEnable	(largeDepthEnable)
1641 	, m_defaultDepth		(0.0f)
1642 	, m_depthClampEnable	(depthClampEnable)
1643 	, m_samples				(samples)
1644 {
1645 }
1646 
~BuiltinFragDepthCase(void)1647 BuiltinFragDepthCase::~BuiltinFragDepthCase(void)
1648 {
1649 }
1650 
initPrograms(SourceCollections & programCollection) const1651 void BuiltinFragDepthCase::initPrograms (SourceCollections& programCollection) const
1652 {
1653 	// Vertex
1654 	{
1655 		// Pass 1
1656 		{
1657 			std::ostringstream vertexSource;
1658 			vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1659 				<< "\n"
1660 				<<  "layout (location = 0) in vec4 position;\n"
1661 				<< "void main()\n"
1662 				<< "{\n"
1663 				<< "	gl_Position = position;\n"
1664 				<< "	gl_PointSize = 1.0;\n"
1665 				<< "}\n";
1666 			programCollection.glslSources.add("FragDepthVert") << glu::VertexSource(vertexSource.str());
1667 		}
1668 
1669 		// Pass 2
1670 		{
1671 			std::ostringstream vertexSource;
1672 			vertexSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1673 				<< "\n"
1674 				<<  "layout (location = 0) in vec4 position;\n"
1675 				<<  "layout (location = 1) out vec2 texCoord;\n"
1676 				<< "void main()\n"
1677 				<< "{\n"
1678 				<< "	gl_Position = position;\n"
1679 				<< "	gl_PointSize = 1.0;\n"
1680 				<< "	texCoord = position.xy/2 + vec2(0.5);\n"
1681 				<< "}\n";
1682 			programCollection.glslSources.add("FragDepthVertPass2") << glu::VertexSource(vertexSource.str());
1683 		}
1684 	}
1685 
1686 	// Fragment
1687 	{
1688 		// Pass 1
1689 		{
1690 			std::ostringstream	fragmentSource;
1691 			fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1692 				<< "\n"
1693 				<< "layout(location = 0) out mediump vec4 color;\n"
1694 				<< "layout (std140, set = 0, binding = 0) uniform control_buffer_t\n"
1695 				<< "{\n"
1696 				<< "	float data[256];\n"
1697 				<< "} control_buffer;\n"
1698 				<< "layout (set = 0, binding = 1, rgba8ui) writeonly uniform uimage2D storageImage;\n"
1699 				<< "float controlDepthValue;\n"
1700 				<< "void recheck(float controlDepthValue)\n"
1701 				<< "{\n"
1702 				<< "	if (gl_FragDepth != controlDepthValue)\n"
1703 				<< "		gl_FragDepth = 1.0;\n"
1704 				<< "}\n"
1705 				<< "void main()\n"
1706 				<< "{\n"
1707 				<< "	const int numSamples = " << m_samples << ";\n"
1708 				<< "	if (int(gl_FragCoord.x) == " << BuiltinFragDepthCaseInstance::RENDERWIDTH/4 << ")\n"
1709 				<< "		discard;\n"
1710 				<< "	highp int index =int(gl_FragCoord.y) * " << BuiltinFragDepthCaseInstance::RENDERHEIGHT << " + int(gl_FragCoord.x);\n"
1711 				<< "	controlDepthValue = control_buffer.data[index];\n"
1712 				<< "	gl_FragDepth = controlDepthValue;\n"
1713 				<< "	const int sampleNdx = int(gl_SampleID);\n"
1714 				<< "	ivec2 imageCoord = ivec2(sampleNdx + int(gl_FragCoord.x) * " << m_samples << ", int(gl_FragCoord.y));\n"
1715 				<< "	imageStore(storageImage, imageCoord, uvec4(1));\n"
1716 				<< "	recheck(controlDepthValue);\n"
1717 				<< "	color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1718 				<< "}\n";
1719 			programCollection.glslSources.add("FragDepthFrag") << glu::FragmentSource(fragmentSource.str());
1720 		}
1721 
1722 		// Pass 2
1723 		{
1724 			const char* multisampleDecoration = m_samples != VK_SAMPLE_COUNT_1_BIT ? "MS" : "";
1725 			std::ostringstream fragmentSource;
1726 			fragmentSource << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1727 				<< "\n"
1728 				<< "layout (location = 0) out mediump vec4 color;\n"
1729 				<< "layout (location = 1) in vec2 texCoord;\n"
1730 				<< "layout (binding = 0, set = 0) uniform sampler2D" << multisampleDecoration << " u_depthTex;\n"
1731 				<< "layout (binding = 1, set = 0, r32f) writeonly uniform image2D u_outImage;\n"
1732 				<< "void main (void)\n"
1733 				<< "{\n"
1734 				<< "	const int numSamples = " << m_samples << ";\n"
1735 				<< "	const int sampleNdx = int(gl_SampleID);\n"
1736 				<< "	ivec2 renderSize = ivec2(" << BuiltinFragDepthCaseInstance::RENDERWIDTH << "," << BuiltinFragDepthCaseInstance::RENDERHEIGHT << ");\n"
1737 				<< "	ivec2 imageCoord = ivec2(int(texCoord.x * renderSize.x), int(texCoord.y * renderSize.y));\n"
1738 				<< "	vec4 depthVal = texelFetch(u_depthTex, imageCoord, sampleNdx);\n"
1739 				<< "	imageStore(u_outImage, ivec2(sampleNdx + int(texCoord.x * renderSize.x) * numSamples, int(texCoord.y * renderSize.y)), depthVal);\n"
1740 				<< "	color = vec4(1.0, 0.0, 0.0, 1.0);\n"
1741 				<< "}\n";
1742 			programCollection.glslSources.add("FragDepthFragPass2") << glu::FragmentSource(fragmentSource.str());
1743 		}
1744 	}
1745 }
1746 
createInstance(Context & context) const1747 TestInstance* BuiltinFragDepthCase::createInstance (Context& context) const
1748 {
1749 	return new BuiltinFragDepthCaseInstance(context, m_topology, m_format, m_largeDepthEnable, m_defaultDepth, m_depthClampEnable, m_samples);
1750 }
1751 
1752 class BuiltinGlFragCoordXYZCaseInstance : public ShaderRenderCaseInstance
1753 {
1754 public:
1755 					BuiltinGlFragCoordXYZCaseInstance	(Context& context);
1756 
1757 	TestStatus		iterate								(void);
1758 	virtual void	setupDefaultInputs					(void);
1759 };
1760 
BuiltinGlFragCoordXYZCaseInstance(Context & context)1761 BuiltinGlFragCoordXYZCaseInstance::BuiltinGlFragCoordXYZCaseInstance (Context& context)
1762 	: ShaderRenderCaseInstance	(context)
1763 {
1764 	m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1765 }
1766 
iterate(void)1767 TestStatus BuiltinGlFragCoordXYZCaseInstance::iterate (void)
1768 {
1769 	const UVec2		viewportSize	= getViewportSize();
1770 	const int		width			= viewportSize.x();
1771 	const int		height			= viewportSize.y();
1772 	const tcu::Vec3	scale			(1.0f / float(width), 1.0f / float(height), 1.0f);
1773 	const float		precision		= 0.00001f;
1774 	const deUint16	indices[6]		=
1775 	{
1776 		2, 1, 3,
1777 		0, 1, 2,
1778 	};
1779 
1780 	setup();
1781 	addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
1782 
1783 	render(4, 2, indices);
1784 
1785 	// Reference image
1786 	for (int y = 0; y < height; y++)
1787 	{
1788 		for (int x = 0; x < width; x++)
1789 		{
1790 			const float	xf			= (float(x) + .5f) / float(width);
1791 			const float	yf			= (float(height - y - 1) + .5f) / float(height);
1792 			const float	z			= (xf + yf) / 2.0f;
1793 			const Vec3	fragCoord	(float(x) + .5f, float(y) + .5f, z);
1794 			const Vec3	scaledFC	= fragCoord*scale;
1795 			const Vec4	color		(scaledFC.x(), scaledFC.y(), scaledFC.z(), 1.0f);
1796 			const Vec4	resultColor	= getResultImage().getAccess().getPixel(x, y);
1797 
1798 			if (de::abs(color.x() - resultColor.x()) > precision ||
1799 				de::abs(color.y() - resultColor.y()) > precision ||
1800 				de::abs(color.z() - resultColor.z()) > precision)
1801 			return TestStatus::fail("Image mismatch");
1802 		}
1803 	}
1804 
1805 	return TestStatus::pass("Result image matches reference");
1806 }
1807 
setupDefaultInputs(void)1808 void BuiltinGlFragCoordXYZCaseInstance::setupDefaultInputs (void)
1809 {
1810 	const float		vertices[]		=
1811 	{
1812 		-1.0f,  1.0f,  0.0f, 1.0f,
1813 		-1.0f, -1.0f,  0.5f, 1.0f,
1814 		 1.0f,  1.0f,  0.5f, 1.0f,
1815 		 1.0f, -1.0f,  1.0f, 1.0f,
1816 	};
1817 
1818 	addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1819 }
1820 
1821 class BuiltinGlFragCoordXYZCase : public TestCase
1822 {
1823 public:
1824 								BuiltinGlFragCoordXYZCase	(TestContext& testCtx, const string& name, const string& description);
1825 	virtual						~BuiltinGlFragCoordXYZCase	(void);
1826 
1827 	void						initPrograms				(SourceCollections& dst) const;
1828 	TestInstance*				createInstance				(Context& context) const;
1829 
1830 private:
1831 								BuiltinGlFragCoordXYZCase	(const BuiltinGlFragCoordXYZCase&);	// not allowed!
1832 	BuiltinGlFragCoordXYZCase&	operator=					(const BuiltinGlFragCoordXYZCase&);	// not allowed!
1833 };
1834 
BuiltinGlFragCoordXYZCase(TestContext & testCtx,const string & name,const string & description)1835 BuiltinGlFragCoordXYZCase::BuiltinGlFragCoordXYZCase (TestContext& testCtx, const string& name, const string& description)
1836 	: TestCase(testCtx, name, description)
1837 {
1838 }
1839 
~BuiltinGlFragCoordXYZCase(void)1840 BuiltinGlFragCoordXYZCase::~BuiltinGlFragCoordXYZCase (void)
1841 {
1842 }
1843 
initPrograms(SourceCollections & dst) const1844 void BuiltinGlFragCoordXYZCase::initPrograms (SourceCollections& dst) const
1845 {
1846 	dst.glslSources.add("vert") << glu::VertexSource(
1847 		"#version 310 es\n"
1848 		"layout(location = 0) in highp vec4 a_position;\n"
1849 		"void main (void)\n"
1850 		"{\n"
1851 		"       gl_Position = a_position;\n"
1852 		"}\n");
1853 
1854 	dst.glslSources.add("frag") << glu::FragmentSource(
1855 		"#version 310 es\n"
1856 		"layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
1857 		"layout(location = 0) out highp vec4 o_color;\n"
1858 		"void main (void)\n"
1859 		"{\n"
1860 		"       o_color = vec4(gl_FragCoord.xyz * u_scale, 1.0);\n"
1861 		"}\n");
1862 }
1863 
createInstance(Context & context) const1864 TestInstance* BuiltinGlFragCoordXYZCase::createInstance (Context& context) const
1865 {
1866 	return new BuiltinGlFragCoordXYZCaseInstance(context);
1867 }
1868 
projectedTriInterpolate(const Vec3 & s,const Vec3 & w,float nx,float ny)1869 inline float projectedTriInterpolate (const Vec3& s, const Vec3& w, float nx, float ny)
1870 {
1871 	return (s[0]*(1.0f-nx-ny)/w[0] + s[1]*ny/w[1] + s[2]*nx/w[2]) / ((1.0f-nx-ny)/w[0] + ny/w[1] + nx/w[2]);
1872 }
1873 
1874 class BuiltinGlFragCoordWCaseInstance : public ShaderRenderCaseInstance
1875 {
1876 public:
1877 					BuiltinGlFragCoordWCaseInstance	(Context& context);
1878 
1879 	TestStatus		iterate							(void);
1880 	virtual void	setupDefaultInputs				(void);
1881 
1882 private:
1883 
1884 	const Vec4		m_w;
1885 
1886 };
1887 
BuiltinGlFragCoordWCaseInstance(Context & context)1888 BuiltinGlFragCoordWCaseInstance::BuiltinGlFragCoordWCaseInstance (Context& context)
1889 	: ShaderRenderCaseInstance	(context)
1890 	, m_w						(1.7f, 2.0f, 1.2f, 1.0f)
1891 {
1892 	m_colorFormat = VK_FORMAT_R16G16B16A16_UNORM;
1893 }
1894 
iterate(void)1895 TestStatus BuiltinGlFragCoordWCaseInstance::iterate (void)
1896 {
1897 	const UVec2		viewportSize	= getViewportSize();
1898 	const int		width			= viewportSize.x();
1899 	const int		height			= viewportSize.y();
1900 	const float		precision		= 0.00001f;
1901 	const deUint16	indices[6]		=
1902 	{
1903 		2, 1, 3,
1904 		0, 1, 2,
1905 	};
1906 
1907 	setup();
1908 	render(4, 2, indices);
1909 
1910 	// Reference image
1911 	for (int y = 0; y < height; y++)
1912 	{
1913 		for (int x = 0; x < width; x++)
1914 		{
1915 			const float	xf			= (float(x) + .5f) / float(width);
1916 			const float	yf			= (float(height - y - 1) +.5f) / float(height);
1917 			const float	oow			= ((xf + yf) < 1.0f)
1918 										? projectedTriInterpolate(Vec3(m_w[0], m_w[1], m_w[2]), Vec3(m_w[0], m_w[1], m_w[2]), xf, yf)
1919 										: projectedTriInterpolate(Vec3(m_w[3], m_w[2], m_w[1]), Vec3(m_w[3], m_w[2], m_w[1]), 1.0f - xf, 1.0f - yf);
1920 			const Vec4	color		(0.0f, oow - 1.0f, 0.0f, 1.0f);
1921 			const Vec4	resultColor	= getResultImage().getAccess().getPixel(x, y);
1922 
1923 			if (de::abs(color.x() - resultColor.x()) > precision ||
1924 				de::abs(color.y() - resultColor.y()) > precision ||
1925 				de::abs(color.z() - resultColor.z()) > precision)
1926 			return TestStatus::fail("Image mismatch");
1927 		}
1928 	}
1929 
1930 	return TestStatus::pass("Result image matches reference");
1931 }
1932 
setupDefaultInputs(void)1933 void BuiltinGlFragCoordWCaseInstance::setupDefaultInputs (void)
1934 {
1935 	const float vertices[] =
1936 	{
1937 		-m_w[0],  m_w[0], 0.0f, m_w[0],
1938 		-m_w[1], -m_w[1], 0.0f, m_w[1],
1939 		 m_w[2],  m_w[2], 0.0f, m_w[2],
1940 		 m_w[3], -m_w[3], 0.0f, m_w[3]
1941 	};
1942 
1943 	addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 4, vertices);
1944 }
1945 
1946 class BuiltinGlFragCoordWCase : public TestCase
1947 {
1948 public:
1949 								BuiltinGlFragCoordWCase		(TestContext& testCtx, const string& name, const string& description);
1950 	virtual						~BuiltinGlFragCoordWCase	(void);
1951 
1952 	void						initPrograms				(SourceCollections& dst) const;
1953 	TestInstance*				createInstance				(Context& context) const;
1954 
1955 private:
1956 								BuiltinGlFragCoordWCase		(const BuiltinGlFragCoordWCase&);	// not allowed!
1957 	BuiltinGlFragCoordWCase&	operator=					(const BuiltinGlFragCoordWCase&);	// not allowed!
1958 };
1959 
BuiltinGlFragCoordWCase(TestContext & testCtx,const string & name,const string & description)1960 BuiltinGlFragCoordWCase::BuiltinGlFragCoordWCase (TestContext& testCtx, const string& name, const string& description)
1961 	: TestCase(testCtx, name, description)
1962 {
1963 }
1964 
~BuiltinGlFragCoordWCase(void)1965 BuiltinGlFragCoordWCase::~BuiltinGlFragCoordWCase (void)
1966 {
1967 }
1968 
initPrograms(SourceCollections & dst) const1969 void BuiltinGlFragCoordWCase::initPrograms (SourceCollections& dst) const
1970 {
1971 	dst.glslSources.add("vert") << glu::VertexSource(
1972 		"#version 310 es\n"
1973 		"layout(location = 0) in highp vec4 a_position;\n"
1974 		"void main (void)\n"
1975 		"{\n"
1976 		"       gl_Position = a_position;\n"
1977 		"}\n");
1978 
1979 	dst.glslSources.add("frag") << glu::FragmentSource(
1980 		"#version 310 es\n"
1981 		"layout(location = 0) out highp vec4 o_color;\n"
1982 		"void main (void)\n"
1983 		"{\n"
1984 		"       o_color = vec4(0.0, 1.0 / gl_FragCoord.w - 1.0, 0.0, 1.0);\n"
1985 		"}\n");
1986 }
1987 
createInstance(Context & context) const1988 TestInstance* BuiltinGlFragCoordWCase::createInstance (Context& context) const
1989 {
1990 	return new BuiltinGlFragCoordWCaseInstance(context);
1991 }
1992 
1993 enum
1994 {
1995 	POINTCOORD_VARIANT_DEFAULT,
1996 	POINTCOORD_VARIANT_UNIFORM_VERTEX,
1997 	POINTCOORD_VARIANT_UNIFORM_FRAGMENT
1998 };
1999 
2000 
2001 class BuiltinGlPointCoordCaseInstance : public ShaderRenderCaseInstance
2002 {
2003 public:
2004 					BuiltinGlPointCoordCaseInstance	(Context& context, int testVariant);
2005 
2006 	TestStatus		iterate								(void);
2007 	virtual void	setupDefaultInputs					(void);
2008 private:
2009 	int				variant;
2010 };
2011 
BuiltinGlPointCoordCaseInstance(Context & context,int testVariant)2012 BuiltinGlPointCoordCaseInstance::BuiltinGlPointCoordCaseInstance (Context& context, int testVariant)
2013 	: ShaderRenderCaseInstance	(context),
2014 	  variant(testVariant)
2015 {
2016 }
2017 
iterate(void)2018 TestStatus BuiltinGlPointCoordCaseInstance::iterate (void)
2019 {
2020 	const UVec2				viewportSize	= getViewportSize();
2021 	const int				width			= viewportSize.x();
2022 	const int				height			= viewportSize.y();
2023 	const float				threshold		= 0.02f;
2024 	const int				numPoints		= 16;
2025 	vector<Vec3>			coords			(numPoints);
2026 	de::Random				rnd				(0x145fa);
2027 	Surface					resImage		(width, height);
2028 	Surface					refImage		(width, height);
2029 	bool					compareOk		= false;
2030 	const tcu::Vec3			scale(1.0f / float(width), 1.0f / float(height), 1.0f);
2031 
2032 	// Compute coordinates.
2033 	{
2034 		const VkPhysicalDeviceLimits&	limits					= m_context.getDeviceProperties().limits;
2035 		const float						minPointSize			= limits.pointSizeRange[0];
2036 		const float						maxPointSize			= limits.pointSizeRange[1];
2037 		const int						pointSizeDeltaMultiples	= de::max(1, deCeilFloatToInt32((maxPointSize - minPointSize) / limits.pointSizeGranularity));
2038 
2039 		TCU_CHECK(minPointSize <= maxPointSize);
2040 
2041 		for (vector<Vec3>::iterator coord = coords.begin(); coord != coords.end(); ++coord)
2042 		{
2043 			coord->x() = rnd.getFloat(-0.9f, 0.9f);
2044 			coord->y() = rnd.getFloat(-0.9f, 0.9f);
2045 			coord->z() = de::min(maxPointSize, minPointSize + float(rnd.getInt(0, pointSizeDeltaMultiples)) * limits.pointSizeGranularity);
2046 		}
2047 	}
2048 
2049 	setup();
2050 
2051 	if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX || variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2052 		addUniform(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, scale);
2053 
2054 	addAttribute(0u, VK_FORMAT_R32G32B32_SFLOAT, deUint32(sizeof(Vec3)), numPoints, &coords[0]);
2055 	render(numPoints, 0, DE_NULL, VK_PRIMITIVE_TOPOLOGY_POINT_LIST);
2056 	copy(resImage.getAccess(), getResultImage().getAccess());
2057 
2058 	// Draw reference
2059 	clear(refImage.getAccess(), m_clearColor);
2060 
2061 	for (vector<Vec3>::const_iterator pointIter = coords.begin(); pointIter != coords.end(); ++pointIter)
2062 	{
2063 		float x = pointIter->x();
2064 		float y = pointIter->y();
2065 		if (variant == POINTCOORD_VARIANT_UNIFORM_VERTEX)
2066 		{
2067 			x *= scale.m_data[0];
2068 			y *= scale.m_data[1];
2069 		}
2070 		const float	centerX	= float(width) *(x*0.5f + 0.5f);
2071 		const float	centerY	= float(height)*(y*0.5f + 0.5f);
2072 		const float	size	= pointIter->z();
2073 		const int	x0		= deRoundFloatToInt32(centerX - size*0.5f);
2074 		const int	y0		= deRoundFloatToInt32(centerY - size*0.5f);
2075 		const int	x1		= deRoundFloatToInt32(centerX + size*0.5f);
2076 		const int	y1		= deRoundFloatToInt32(centerY + size*0.5f);
2077 		const int	w		= x1-x0;
2078 		const int	h		= y1-y0;
2079 
2080 		for (int yo = 0; yo < h; yo++)
2081 		{
2082 			for (int xo = 0; xo < w; xo++)
2083 			{
2084 				const int		dx		= x0+xo;
2085 				const int		dy		= y0+yo;
2086 				const float		fragX	= float(dx) + 0.5f;
2087 				const float		fragY	= float(dy) + 0.5f;
2088 				const float		s		= 0.5f + (fragX - centerX) / size;
2089 				const float		t		= 0.5f + (fragY - centerY) / size;
2090 				Vec4			color	(s, t, 0.0f, 1.0f);
2091 
2092 				if (variant == POINTCOORD_VARIANT_UNIFORM_FRAGMENT)
2093 				{
2094 					color.m_data[0] *= scale.m_data[0];
2095 					color.m_data[1] *= scale.m_data[1];
2096 					color.m_data[2] *= scale.m_data[2];
2097 				}
2098 
2099 				if (de::inBounds(dx, 0, refImage.getWidth()) && de::inBounds(dy, 0, refImage.getHeight()))
2100 					refImage.setPixel(dx, dy, RGBA(color));
2101 			}
2102 		}
2103 	}
2104 
2105 	compareOk = fuzzyCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2106 
2107 	if (compareOk)
2108 		return TestStatus::pass("Result image matches reference");
2109 	else
2110 		return TestStatus::fail("Image mismatch");
2111 }
2112 
setupDefaultInputs(void)2113 void BuiltinGlPointCoordCaseInstance::setupDefaultInputs (void)
2114 {
2115 }
2116 
2117 class BuiltinGlPointCoordCase : public TestCase
2118 {
2119 public:
2120 								BuiltinGlPointCoordCase	(TestContext& testCtx, const string& name, const string& description, int testVariant);
2121 	virtual						~BuiltinGlPointCoordCase	(void);
2122 
2123 	void						initPrograms				(SourceCollections& dst) const;
2124 	TestInstance*				createInstance				(Context& context) const;
2125 
2126 private:
2127 	int							variant;
2128 								BuiltinGlPointCoordCase	(const BuiltinGlPointCoordCase&);	// not allowed!
2129 	BuiltinGlPointCoordCase&	operator=					(const BuiltinGlPointCoordCase&);	// not allowed!
2130 };
2131 
BuiltinGlPointCoordCase(TestContext & testCtx,const string & name,const string & description,int testVariant)2132 BuiltinGlPointCoordCase::BuiltinGlPointCoordCase (TestContext& testCtx, const string& name, const string& description, int testVariant)
2133 	: TestCase(testCtx, name, description),
2134 	  variant(testVariant)
2135 {
2136 }
2137 
~BuiltinGlPointCoordCase(void)2138 BuiltinGlPointCoordCase::~BuiltinGlPointCoordCase (void)
2139 {
2140 }
2141 
initPrograms(SourceCollections & dst) const2142 void BuiltinGlPointCoordCase::initPrograms (SourceCollections& dst) const
2143 {
2144 	switch (variant)
2145 	{
2146 	case POINTCOORD_VARIANT_UNIFORM_FRAGMENT:
2147 		dst.glslSources.add("vert") << glu::VertexSource(
2148 			"#version 310 es\n"
2149 			"layout(location = 0) in highp vec3 a_position;\n"
2150 			"void main (void)\n"
2151 			"{\n"
2152 			"    gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2153 			"    gl_PointSize = a_position.z;\n"
2154 			"}\n");
2155 
2156 		dst.glslSources.add("frag") << glu::FragmentSource(
2157 			"#version 310 es\n"
2158 			"layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2159 			"layout(location = 0) out lowp vec4 o_color;\n"
2160 			"void main (void)\n"
2161 			"{\n"
2162 			"    o_color = vec4(gl_PointCoord, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2163 			"}\n");
2164 		break;
2165 	case POINTCOORD_VARIANT_UNIFORM_VERTEX:
2166 		dst.glslSources.add("vert") << glu::VertexSource(
2167 			"#version 310 es\n"
2168 			"layout(set=0, binding=0) uniform Scale { highp vec3 u_scale; };\n"
2169 			"layout(location = 0) in highp vec3 a_position;\n"
2170 			"void main (void)\n"
2171 			"{\n"
2172 			"    gl_Position = vec4(a_position.xy, 0.0, 1.0) * vec4(u_scale, 1.0);\n"
2173 			"    gl_PointSize = a_position.z;\n"
2174 			"}\n");
2175 
2176 		dst.glslSources.add("frag") << glu::FragmentSource(
2177 			"#version 310 es\n"
2178 			"layout(location = 0) out lowp vec4 o_color;\n"
2179 			"void main (void)\n"
2180 			"{\n"
2181 			"    o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2182 			"}\n");
2183 		break;
2184 	default: // POINTCOORD_VARIANT_DEFAULT
2185 		dst.glslSources.add("vert") << glu::VertexSource(
2186 			"#version 310 es\n"
2187 			"layout(location = 0) in highp vec3 a_position;\n"
2188 			"void main (void)\n"
2189 			"{\n"
2190 			"    gl_Position = vec4(a_position.xy, 0.0, 1.0);\n"
2191 			"    gl_PointSize = a_position.z;\n"
2192 			"}\n");
2193 
2194 		dst.glslSources.add("frag") << glu::FragmentSource(
2195 			"#version 310 es\n"
2196 			"layout(location = 0) out lowp vec4 o_color;\n"
2197 			"void main (void)\n"
2198 			"{\n"
2199 			"    o_color = vec4(gl_PointCoord, 0.0, 1.0);\n"
2200 			"}\n");
2201 	}
2202 }
2203 
createInstance(Context & context) const2204 TestInstance* BuiltinGlPointCoordCase::createInstance (Context& context) const
2205 {
2206 	return new BuiltinGlPointCoordCaseInstance(context, variant);
2207 }
2208 
2209 enum ShaderInputTypeBits
2210 {
2211 	SHADER_INPUT_BUILTIN_BIT	= 0x01,
2212 	SHADER_INPUT_VARYING_BIT	= 0x02,
2213 	SHADER_INPUT_CONSTANT_BIT	= 0x04
2214 };
2215 
2216 typedef deUint16 ShaderInputTypes;
2217 
shaderInputTypeToString(ShaderInputTypes type)2218 string shaderInputTypeToString (ShaderInputTypes type)
2219 {
2220 	string typeString = "input";
2221 
2222 	if (type == 0)
2223 		return "input_none";
2224 
2225 	if (type & SHADER_INPUT_BUILTIN_BIT)
2226 		typeString += "_builtin";
2227 
2228 	if (type & SHADER_INPUT_VARYING_BIT)
2229 		typeString += "_varying";
2230 
2231 	if (type & SHADER_INPUT_CONSTANT_BIT)
2232 		typeString += "_constant";
2233 
2234 	return typeString;
2235 }
2236 
2237 class BuiltinInputVariationsCaseInstance : public ShaderRenderCaseInstance
2238 {
2239 public:
2240 							BuiltinInputVariationsCaseInstance	(Context& context, const ShaderInputTypes shaderInputTypes);
2241 
2242 	TestStatus				iterate								(void);
2243 	virtual void			setupDefaultInputs					(void);
2244 	virtual void			updatePushConstants					(vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout);
2245 
2246 private:
2247 	const ShaderInputTypes	m_shaderInputTypes;
2248 	const Vec4				m_constantColor;
2249 };
2250 
BuiltinInputVariationsCaseInstance(Context & context,const ShaderInputTypes shaderInputTypes)2251 BuiltinInputVariationsCaseInstance::BuiltinInputVariationsCaseInstance (Context& context, const ShaderInputTypes shaderInputTypes)
2252 	: ShaderRenderCaseInstance	(context)
2253 	, m_shaderInputTypes		(shaderInputTypes)
2254 	, m_constantColor			(0.1f, 0.05f, 0.2f, 0.0f)
2255 {
2256 }
2257 
iterate(void)2258 TestStatus BuiltinInputVariationsCaseInstance::iterate (void)
2259 {
2260 	const UVec2					viewportSize	= getViewportSize();
2261 	const int					width			= viewportSize.x();
2262 	const int					height			= viewportSize.y();
2263 	const tcu::RGBA				threshold		(2, 2, 2, 2);
2264 	Surface						resImage		(width, height);
2265 	Surface						refImage		(width, height);
2266 	bool						compareOk		= false;
2267 	const VkPushConstantRange	pcRanges		=
2268 	{
2269 		VK_SHADER_STAGE_FRAGMENT_BIT,	// VkShaderStageFlags	stageFlags;
2270 		0u,								// deUint32				offset;
2271 		sizeof(Vec4)					// deUint32				size;
2272 	};
2273 	const deUint16				indices[12]		=
2274 	{
2275 		0, 4, 1,
2276 		0, 5, 4,
2277 		1, 2, 3,
2278 		1, 3, 4
2279 	};
2280 
2281 	setup();
2282 
2283 	if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2284 		setPushConstantRanges(1, &pcRanges);
2285 
2286 	render(6, 4, indices);
2287 	copy(resImage.getAccess(), getResultImage().getAccess());
2288 
2289 	// Reference image
2290 	for (int y = 0; y < refImage.getHeight(); y++)
2291 	{
2292 		for (int x = 0; x < refImage.getWidth(); x++)
2293 		{
2294 			Vec4 color (0.1f, 0.2f, 0.3f, 1.0f);
2295 
2296 			if (((m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT) && (x < refImage.getWidth() / 2)) ||
2297 				!(m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT))
2298 			{
2299 				if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2300 				{
2301 					const float xf = (float(x)+.5f) / float(refImage.getWidth());
2302 					color += Vec4(0.6f * (1 - xf), 0.6f * xf, 0.0f, 0.0f);
2303 				}
2304 				else
2305 					color += Vec4(0.3f, 0.2f, 0.1f, 0.0f);
2306 			}
2307 
2308 			if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2309 				color += m_constantColor;
2310 
2311 			refImage.setPixel(x, y, RGBA(color));
2312 		}
2313 	}
2314 
2315 	compareOk = pixelThresholdCompare(m_context.getTestContext().getLog(), "Result", "Image comparison result", refImage, resImage, threshold, COMPARE_LOG_RESULT);
2316 
2317 	if (compareOk)
2318 		return TestStatus::pass("Result image matches reference");
2319 	else
2320 		return TestStatus::fail("Image mismatch");
2321 }
2322 
setupDefaultInputs(void)2323 void BuiltinInputVariationsCaseInstance::setupDefaultInputs (void)
2324 {
2325 	const float vertices[] =
2326 	{
2327 		-1.0f, -1.0f, 0.0f, 1.0f,
2328 		 0.0f, -1.0f, 0.0f, 1.0f,
2329 		 1.0f, -1.0f, 0.0f, 1.0f,
2330 		 1.0f,  1.0f, 0.0f, 1.0f,
2331 		 0.0f,  1.0f, 0.0f, 1.0f,
2332 		-1.0f,  1.0f, 0.0f, 1.0f
2333 	};
2334 
2335 	addAttribute(0u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, vertices);
2336 
2337 	if (m_shaderInputTypes & SHADER_INPUT_VARYING_BIT)
2338 	{
2339 		const float colors[] =
2340 		{
2341 			 0.6f,  0.0f, 0.0f, 1.0f,
2342 			 0.3f,  0.3f, 0.0f, 1.0f,
2343 			 0.0f,  0.6f, 0.0f, 1.0f,
2344 			 0.0f,  0.6f, 0.0f, 1.0f,
2345 			 0.3f,  0.3f, 0.0f, 1.0f,
2346 			 0.6f,  0.0f, 0.0f, 1.0f
2347 		};
2348 		addAttribute(1u, VK_FORMAT_R32G32B32A32_SFLOAT, deUint32(sizeof(float) * 4), 6, colors);
2349 	}
2350 }
2351 
updatePushConstants(vk::VkCommandBuffer commandBuffer,vk::VkPipelineLayout pipelineLayout)2352 void BuiltinInputVariationsCaseInstance::updatePushConstants (vk::VkCommandBuffer commandBuffer, vk::VkPipelineLayout pipelineLayout)
2353 {
2354 	if (m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT)
2355 	{
2356 		const DeviceInterface& vk = m_context.getDeviceInterface();
2357 		vk.cmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(Vec4), &m_constantColor);
2358 	}
2359 }
2360 
2361 class BuiltinInputVariationsCase : public TestCase
2362 {
2363 public:
2364 								BuiltinInputVariationsCase	(TestContext& testCtx, const string& name, const string& description, const ShaderInputTypes shaderInputTypes);
2365 	virtual						~BuiltinInputVariationsCase	(void);
2366 
2367 	void						initPrograms				(SourceCollections& dst) const;
2368 	TestInstance*				createInstance				(Context& context) const;
2369 
2370 private:
2371 								BuiltinInputVariationsCase	(const BuiltinInputVariationsCase&);	// not allowed!
2372 	BuiltinInputVariationsCase&	operator=					(const BuiltinInputVariationsCase&);	// not allowed!
2373 	const ShaderInputTypes		m_shaderInputTypes;
2374 };
2375 
BuiltinInputVariationsCase(TestContext & testCtx,const string & name,const string & description,ShaderInputTypes shaderInputTypes)2376 BuiltinInputVariationsCase::BuiltinInputVariationsCase (TestContext& testCtx, const string& name, const string& description, ShaderInputTypes shaderInputTypes)
2377 	: TestCase				(testCtx, name, description)
2378 	, m_shaderInputTypes	(shaderInputTypes)
2379 {
2380 }
2381 
~BuiltinInputVariationsCase(void)2382 BuiltinInputVariationsCase::~BuiltinInputVariationsCase (void)
2383 {
2384 }
2385 
initPrograms(SourceCollections & dst) const2386 void BuiltinInputVariationsCase::initPrograms (SourceCollections& dst) const
2387 {
2388 	map<string, string>			vertexParams;
2389 	map<string, string>			fragmentParams;
2390 	const tcu::StringTemplate	vertexCodeTemplate		(
2391 		"#version 450\n"
2392 		"layout(location = 0) in highp vec4 a_position;\n"
2393 		"out gl_PerVertex {\n"
2394 		"	vec4 gl_Position;\n"
2395 		"};\n"
2396 		"${VARYING_DECL}"
2397 		"void main (void)\n"
2398 		"{\n"
2399 		"    gl_Position = a_position;\n"
2400 		"    ${VARYING_USAGE}"
2401 		"}\n");
2402 
2403 	const tcu::StringTemplate	fragmentCodeTemplate	(
2404 		"#version 450\n"
2405 		"${VARYING_DECL}"
2406 		"${CONSTANT_DECL}"
2407 		"layout(location = 0) out highp vec4 o_color;\n"
2408 		"void main (void)\n"
2409 		"{\n"
2410 		"    o_color = vec4(0.1, 0.2, 0.3, 1.0);\n"
2411 		"    ${BUILTIN_USAGE}"
2412 		"    ${VARYING_USAGE}"
2413 		"    ${CONSTANT_USAGE}"
2414 		"}\n");
2415 
2416 	vertexParams["VARYING_DECL"]		=
2417 		m_shaderInputTypes & SHADER_INPUT_VARYING_BIT	? "layout(location = 1) in highp vec4 a_color;\n"
2418 														  "layout(location = 0) out highp vec4 v_color;\n"
2419 														: "";
2420 
2421 	vertexParams["VARYING_USAGE"]		=
2422 		m_shaderInputTypes & SHADER_INPUT_VARYING_BIT	? "v_color = a_color;\n"
2423 														: "";
2424 
2425 	fragmentParams["VARYING_DECL"]		=
2426 		m_shaderInputTypes & SHADER_INPUT_VARYING_BIT	? "layout(location = 0) in highp vec4 a_color;\n"
2427 														: "";
2428 
2429 	fragmentParams["CONSTANT_DECL"]		=
2430 		m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT	? "layout(push_constant) uniform PCBlock {\n"
2431 														  "  vec4 color;\n"
2432 														  "} pc;\n"
2433 														: "";
2434 
2435 	fragmentParams["BUILTIN_USAGE"]		=
2436 		m_shaderInputTypes & SHADER_INPUT_BUILTIN_BIT	? "if (gl_FrontFacing)\n"
2437 														: "";
2438 
2439 	fragmentParams["VARYING_USAGE"]		=
2440 		m_shaderInputTypes & SHADER_INPUT_VARYING_BIT	? "o_color += vec4(a_color.xyz, 0.0);\n"
2441 														: "o_color += vec4(0.3, 0.2, 0.1, 0.0);\n";
2442 
2443 
2444 	fragmentParams["CONSTANT_USAGE"]	=
2445 		m_shaderInputTypes & SHADER_INPUT_CONSTANT_BIT	? "o_color += pc.color;\n"
2446 														: "";
2447 
2448 	dst.glslSources.add("vert") << glu::VertexSource(vertexCodeTemplate.specialize(vertexParams));
2449 	dst.glslSources.add("frag") << glu::FragmentSource(fragmentCodeTemplate.specialize(fragmentParams));
2450 }
2451 
createInstance(Context & context) const2452 TestInstance* BuiltinInputVariationsCase::createInstance (Context& context) const
2453 {
2454 	return new BuiltinInputVariationsCaseInstance(context, m_shaderInputTypes);
2455 }
2456 
2457 } // anonymous
2458 
createBuiltinVarTests(TestContext & testCtx)2459 TestCaseGroup* createBuiltinVarTests (TestContext& testCtx)
2460 {
2461 	de::MovePtr<TestCaseGroup> builtinGroup			(new TestCaseGroup(testCtx, "builtin_var", "Shader builtin variable tests."));
2462 	de::MovePtr<TestCaseGroup> simpleGroup			(new TestCaseGroup(testCtx, "simple", "Simple cases."));
2463 	de::MovePtr<TestCaseGroup> inputVariationsGroup	(new TestCaseGroup(testCtx, "input_variations", "Input type variation tests."));
2464 	de::MovePtr<TestCaseGroup> frontFacingGroup		(new TestCaseGroup(testCtx, "frontfacing", "Test gl_Frontfacing keyword."));
2465 	de::MovePtr<TestCaseGroup> fragDepthGroup		(new TestCaseGroup(testCtx, "fragdepth", "Test gl_FragDepth keyword."));
2466 	de::MovePtr<TestCaseGroup> fragCoordMsaaGroup	(new TestCaseGroup(testCtx, "fragcoord_msaa", "Test interation between gl_FragCoord and msaa"));
2467 	de::MovePtr<TestCaseGroup> fragCoordMsaaInputGroup	(new TestCaseGroup(testCtx, "fragcoord_msaa_input", "Test interation between gl_FragCoord and msaa"));
2468 
2469 	simpleGroup->addChild(new BuiltinGlFragCoordXYZCase(testCtx, "fragcoord_xyz", "FragCoord xyz test"));
2470 	simpleGroup->addChild(new BuiltinGlFragCoordWCase(testCtx, "fragcoord_w", "FragCoord w test"));
2471 	simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord", "PointCoord test", POINTCOORD_VARIANT_DEFAULT));
2472 	simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_frag", "PointCoord test with fragment uniform", POINTCOORD_VARIANT_UNIFORM_FRAGMENT));
2473 	simpleGroup->addChild(new BuiltinGlPointCoordCase(testCtx, "pointcoord_uniform_vert", "PointCoord test with vertex uniform", POINTCOORD_VARIANT_UNIFORM_VERTEX));
2474 
2475 	// FragCoord_msaa
2476 	{
2477 		static const struct FragCoordMsaaCaseList
2478 		{
2479 			const char*				name;
2480 			const char*				description;
2481 			VkSampleCountFlagBits	sampleCount;
2482 		} fragCoordMsaaCaseList[] =
2483 		{
2484 			{ "1_bit",	"Test FragCoord locations with 1 sample",	VK_SAMPLE_COUNT_1_BIT },
2485 			{ "2_bit",	"Test FragCoord locations with 2 samples",	VK_SAMPLE_COUNT_2_BIT },
2486 			{ "4_bit",	"Test FragCoord locations with 4 samples",	VK_SAMPLE_COUNT_4_BIT },
2487 			{ "8_bit",	"Test FragCoord locations with 8 samples",	VK_SAMPLE_COUNT_8_BIT },
2488 			{ "16_bit",	"Test FragCoord locations with 16 samples",	VK_SAMPLE_COUNT_16_BIT },
2489 			{ "32_bit",	"Test FragCoord locations with 32 samples",	VK_SAMPLE_COUNT_32_BIT },
2490 			{ "64_bit",	"Test FragCoord locaitons with 64 samples",	VK_SAMPLE_COUNT_64_BIT },
2491 		};
2492 
2493 		// Standard sample tests
2494 		std::vector<uint32_t> sampleMaskArray;
2495 
2496 		for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2497 		{
2498 			fragCoordMsaaGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, true));
2499 			fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, fragCoordMsaaCaseList[caseNdx].name, fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, true, sampleMaskArray, false, false));
2500 		}
2501 
2502 		sampleMaskArray.push_back(1u);
2503 
2504 		// No sample shading tests
2505 		for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2506 		{
2507 			fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, false, false));
2508 		}
2509 
2510 		// No sample shading tests with centroid interpolation decoration
2511 		for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(fragCoordMsaaCaseList); caseNdx++)
2512 		{
2513 			fragCoordMsaaInputGroup->addChild(new BuiltinFragCoordMsaaTestCase(testCtx, (std::string(fragCoordMsaaCaseList[caseNdx].name) + "_no_sample_shading_centroid_interpolation").c_str(), fragCoordMsaaCaseList[caseNdx].description, fragCoordMsaaCaseList[caseNdx].sampleCount, false, sampleMaskArray, true, false));
2514 		}
2515 	}
2516 
2517 	// gl_FrontFacing tests
2518 	{
2519 		static const struct PrimitiveTable
2520 		{
2521 			const char*				name;
2522 			const char*				desc;
2523 			VkPrimitiveTopology		primitive;
2524 		} frontfacingCases[] =
2525 		{
2526 			{ "point_list",		"Test that points are frontfacing",							VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2527 			{ "line_list",		"Test that lines are frontfacing",							VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2528 			{ "triangle_list",	"Test that triangles can be frontfacing or backfacing",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST },
2529 			{ "triangle_strip",	"Test that traiangle strips can be front or back facing",	VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2530 			{ "triangle_fan",	"Test that triangle fans can be front or back facing",		VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN },
2531 		};
2532 
2533 		for (deUint32 ndx = 0; ndx < DE_LENGTH_OF_ARRAY(frontfacingCases); ndx++)
2534 			frontFacingGroup->addChild(new BuiltinGlFrontFacingCase(testCtx, frontfacingCases[ndx].primitive, frontfacingCases[ndx].name, frontfacingCases[ndx].desc));
2535 	}
2536 
2537 	// gl_FragDepth
2538 	{
2539 		static const struct PrimitiveTopologyTable
2540 		{
2541 			std::string			name;
2542 			std::string			desc;
2543 			VkPrimitiveTopology	prim;
2544 		} primitiveTopologyTable[] =
2545 		{
2546 			{ "point_list",		"test that points respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_POINT_LIST },
2547 			{ "line_list",		"test taht lines respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_LINE_LIST },
2548 			{ "triangle_list",	"test that triangles respect gl_fragdepth", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP },
2549 		};
2550 
2551 		static const struct TestCaseTable
2552 		{
2553 			VkFormat				format;
2554 			std::string				name;
2555 			bool					largeDepthEnable;
2556 			bool					depthClampEnable;
2557 			VkSampleCountFlagBits	samples;
2558 		} testCaseTable[] =
2559 		{
2560 			{ VK_FORMAT_D16_UNORM,				"d16_unorm_no_depth_clamp",				false,	false,	VK_SAMPLE_COUNT_1_BIT },
2561 			{ VK_FORMAT_X8_D24_UNORM_PACK32,	"x8_d24_unorm_pack32_no_depth_clamp",	false,	false,	VK_SAMPLE_COUNT_1_BIT },
2562 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_no_depth_clamp",			false,	false,	VK_SAMPLE_COUNT_1_BIT },
2563 			{ VK_FORMAT_D16_UNORM_S8_UINT,		"d16_unorm_s8_uint_no_depth_clamp",		false,	false,	VK_SAMPLE_COUNT_1_BIT },
2564 			{ VK_FORMAT_D24_UNORM_S8_UINT,		"d24_unorm_s8_uint_no_depth_clamp",		false,	false,	VK_SAMPLE_COUNT_1_BIT },
2565 			{ VK_FORMAT_D32_SFLOAT_S8_UINT,		"d32_sfloat_s8_uint_no_depth_clamp",	false,	false,	VK_SAMPLE_COUNT_1_BIT },
2566 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_large_depth",				true,	false,	VK_SAMPLE_COUNT_1_BIT },
2567 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat",							false,	true,	VK_SAMPLE_COUNT_1_BIT },
2568 			{ VK_FORMAT_D32_SFLOAT_S8_UINT,		"d32_sfloat_s8_uint",					false,	true,	VK_SAMPLE_COUNT_1_BIT },
2569 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_2",				false,	false,	VK_SAMPLE_COUNT_2_BIT },
2570 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_4",				false,	false,	VK_SAMPLE_COUNT_4_BIT },
2571 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_8",				false,	false,	VK_SAMPLE_COUNT_8_BIT },
2572 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_16",			false,	false,	VK_SAMPLE_COUNT_16_BIT },
2573 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_32",			false,	false,	VK_SAMPLE_COUNT_32_BIT },
2574 			{ VK_FORMAT_D32_SFLOAT,				"d32_sfloat_multisample_64",			false,	false,	VK_SAMPLE_COUNT_64_BIT },
2575 		};
2576 
2577 		for (deUint32 primNdx = 0;  primNdx < DE_LENGTH_OF_ARRAY(primitiveTopologyTable); primNdx++)
2578 		{
2579 			for (deUint32 caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(testCaseTable); caseNdx++)
2580 				fragDepthGroup->addChild(new BuiltinFragDepthCase(testCtx, (primitiveTopologyTable[primNdx].name+"_" + testCaseTable[caseNdx].name).c_str(), primitiveTopologyTable[primNdx].desc.c_str(),
2581 							primitiveTopologyTable[primNdx].prim, testCaseTable[caseNdx].format, testCaseTable[caseNdx].largeDepthEnable, testCaseTable[caseNdx].depthClampEnable, testCaseTable[caseNdx].samples));
2582 
2583 		}
2584 	}
2585 
2586 	builtinGroup->addChild(frontFacingGroup.release());
2587 	builtinGroup->addChild(fragDepthGroup.release());
2588 	builtinGroup->addChild(fragCoordMsaaGroup.release());
2589 	builtinGroup->addChild(fragCoordMsaaInputGroup.release());
2590 	builtinGroup->addChild(simpleGroup.release());
2591 
2592 	for (deUint16 shaderType = 0; shaderType <= (SHADER_INPUT_BUILTIN_BIT | SHADER_INPUT_VARYING_BIT | SHADER_INPUT_CONSTANT_BIT); ++shaderType)
2593 	{
2594 		inputVariationsGroup->addChild(new BuiltinInputVariationsCase(testCtx, shaderInputTypeToString(shaderType), "Input variation test", shaderType));
2595 	}
2596 
2597 	builtinGroup->addChild(inputVariationsGroup.release());
2598 	return builtinGroup.release();
2599 }
2600 
2601 } // sr
2602 } // vkt
2603