• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 Google LLC
6  * Copyright (c) 2019 The Khronos Group Inc.
7  * Copyright (c) 2023 LunarG, Inc.
8  * Copyright (c) 2023 Nintendo
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *      http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  *
22  *//*!
23  * \file
24  * \brief Miscellaneous pipeline tests.
25  *//*--------------------------------------------------------------------*/
26 
27 #include <string>
28 #include <memory>
29 #include <vector>
30 #include <algorithm>
31 #include <array>
32 #include <numeric>
33 #include <memory>
34 
35 #include "vkPipelineConstructionUtil.hpp"
36 #include "vktTestGroupUtil.hpp"
37 #include "vktAmberTestCase.hpp"
38 #include "vktPipelineMiscTests.hpp"
39 
40 #include "vkDefs.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "vkImageUtil.hpp"
43 #include "deStringUtil.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkCmdUtil.hpp"
47 #include "vkObjUtil.hpp"
48 #include "vkImageWithMemory.hpp"
49 #include "vkBarrierUtil.hpp"
50 #include "vkBufferWithMemory.hpp"
51 #include "vkBuilderUtil.hpp"
52 #include "vktPipelineReferenceRenderer.hpp"
53 #include "vkBuilderUtil.hpp"
54 
55 namespace vkt
56 {
57 namespace pipeline
58 {
59 
60 using namespace vk;
61 
62 namespace
63 {
64 
65 enum AmberFeatureBits
66 {
67 	AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS	= (1 <<	0),
68 	AMBER_FEATURE_TESSELATION_SHADER					= (1 <<	1),
69 	AMBER_FEATURE_GEOMETRY_SHADER						= (1 <<	2),
70 };
71 
72 using AmberFeatureFlags = deUint32;
73 
74 #ifndef CTS_USES_VULKANSC
getFeatureList(AmberFeatureFlags flags)75 std::vector<std::string> getFeatureList (AmberFeatureFlags flags)
76 {
77 	std::vector<std::string> requirements;
78 
79 	if (flags & AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS)
80 		requirements.push_back("Features.vertexPipelineStoresAndAtomics");
81 
82 	if (flags & AMBER_FEATURE_TESSELATION_SHADER)
83 		requirements.push_back("Features.tessellationShader");
84 
85 	if (flags & AMBER_FEATURE_GEOMETRY_SHADER)
86 		requirements.push_back("Features.geometryShader");
87 
88 	return requirements;
89 }
90 #endif // CTS_USES_VULKANSC
91 
addMonolithicAmberTests(tcu::TestCaseGroup * tests)92 void addMonolithicAmberTests (tcu::TestCaseGroup* tests)
93 {
94 #ifndef CTS_USES_VULKANSC
95 	tcu::TestContext& testCtx = tests->getTestContext();
96 
97 	// Shader test files are saved in <path>/external/vulkancts/data/vulkan/amber/pipeline/<basename>.amber
98 	struct Case {
99 		const char*			basename;
100 		AmberFeatureFlags	flags;
101 	};
102 
103 	const Case cases[] =
104 	{
105 		{
106 			"position_to_ssbo",
107 			(AMBER_FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS),
108 		},
109 		{
110 			"primitive_id_from_tess",
111 			(AMBER_FEATURE_TESSELATION_SHADER | AMBER_FEATURE_GEOMETRY_SHADER),
112 		},
113 	};
114 	for (unsigned i = 0; i < DE_LENGTH_OF_ARRAY(cases) ; ++i)
115 	{
116 		std::string					file			= std::string(cases[i].basename) + ".amber";
117 		std::vector<std::string>	requirements	= getFeatureList(cases[i].flags);
118 		cts_amber::AmberTestCase	*testCase		= cts_amber::createAmberTestCase(testCtx, cases[i].basename, "pipeline", file, requirements);
119 
120 		tests->addChild(testCase);
121 	}
122 #else
123 	DE_UNREF(tests);
124 #endif
125 }
126 
127 class ImplicitPrimitiveIDPassthroughCase : public vkt::TestCase
128 {
129 public:
ImplicitPrimitiveIDPassthroughCase(tcu::TestContext & testCtx,const std::string & name,const PipelineConstructionType pipelineConstructionType,bool withTessellation)130 	ImplicitPrimitiveIDPassthroughCase		(tcu::TestContext&                  testCtx,
131 											 const std::string&                 name,
132 											 const PipelineConstructionType		pipelineConstructionType,
133 											 bool withTessellation)
134 		: vkt::TestCase(testCtx, name)
135 		, m_pipelineConstructionType(pipelineConstructionType)
136 		, m_withTessellationPassthrough(withTessellation)
137 	{
138 	}
~ImplicitPrimitiveIDPassthroughCase(void)139 	~ImplicitPrimitiveIDPassthroughCase		    (void) {}
140 	void			initPrograms				(SourceCollections& programCollection) const override;
141 	void			checkSupport				(Context& context) const override;
142 	TestInstance*	createInstance				(Context& context) const override;
143 
144 	const PipelineConstructionType m_pipelineConstructionType;
145 private:
146 	bool m_withTessellationPassthrough;
147 };
148 
149 class ImplicitPrimitiveIDPassthroughInstance : public vkt::TestInstance
150 {
151 public:
ImplicitPrimitiveIDPassthroughInstance(Context & context,const PipelineConstructionType pipelineConstructionType,bool withTessellation)152 	ImplicitPrimitiveIDPassthroughInstance	(Context&                           context,
153 											 const PipelineConstructionType		pipelineConstructionType,
154 											 bool withTessellation)
155 		: vkt::TestInstance				(context)
156 		, m_pipelineConstructionType	(pipelineConstructionType)
157 		, m_renderSize					(2, 2)
158 		, m_extent(makeExtent3D			(m_renderSize.x(), m_renderSize.y(), 1u))
159 		, m_graphicsPipeline			(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), pipelineConstructionType)
160 		, m_withTessellationPassthrough	(withTessellation)
161 	{
162 	}
~ImplicitPrimitiveIDPassthroughInstance(void)163 	~ImplicitPrimitiveIDPassthroughInstance	(void) {}
164 	tcu::TestStatus		iterate				(void) override;
165 
166 private:
167 	PipelineConstructionType	m_pipelineConstructionType;
168 	const tcu::UVec2            m_renderSize;
169 	const VkExtent3D		    m_extent;
170 	const VkFormat		        m_format = VK_FORMAT_R8G8B8A8_UNORM;
171 	GraphicsPipelineWrapper		m_graphicsPipeline;
172 	bool                        m_withTessellationPassthrough;
173 };
174 
createInstance(Context & context) const175 TestInstance* ImplicitPrimitiveIDPassthroughCase::createInstance (Context& context) const
176 {
177 	return new ImplicitPrimitiveIDPassthroughInstance(context, m_pipelineConstructionType, m_withTessellationPassthrough);
178 }
179 
checkSupport(Context & context) const180 void ImplicitPrimitiveIDPassthroughCase::checkSupport (Context &context) const
181 {
182 	if (m_withTessellationPassthrough)
183 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
184 
185 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
186 
187 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
188 }
189 
initPrograms(SourceCollections & sources) const190 void ImplicitPrimitiveIDPassthroughCase::initPrograms(SourceCollections& sources) const
191 {
192 	std::ostringstream vert;
193 	// Generate a vertically split framebuffer, filled with red on the
194 	// left, and a green on the right.
195 	vert
196 		<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
197 		<< "void main ()\n"
198 		<< "{\n"
199 		<< "    switch (gl_VertexIndex) {\n"
200 		<< "        case 0:\n"
201 		<< "            gl_Position = vec4(-3.0, -1.0, 0.0, 1.0);\n"
202 		<< "            break;\n"
203 		<< "        case 1:\n"
204 		<< "            gl_Position = vec4(0.0, 3.0, 0.0, 1.0);\n"
205 		<< "            break;\n"
206 		<< "        case 2:\n"
207 		<< "            gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
208 		<< "            break;\n"
209 		<< "        case 3:\n"
210 		<< "            gl_Position = vec4(0.0, -1.0, 0.0, 1.0);\n"
211 		<< "            break;\n"
212 		<< "        case 4:\n"
213 		<< "            gl_Position = vec4(3.0, -1.0, 0.0, 1.0);\n"
214 		<< "            break;\n"
215 		<< "        case 5:\n"
216 		<< "            gl_Position = vec4(0.0, 3.0, 0.0, 1.0);\n"
217 		<< "            break;\n"
218 		<< "    }\n"
219 		<< "}\n"
220 		;
221 	sources.glslSources.add("vert") << glu::VertexSource(vert.str());
222 
223 	if (m_withTessellationPassthrough) {
224 		std::ostringstream tsc;
225 		tsc
226 			<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
227 			<< "layout (vertices = 3) out;\n"
228 			<< "\n"
229 			<< "void main ()\n"
230 			<< "{\n"
231 			<< "    if (gl_InvocationID == 0) {\n"
232 			<< "        gl_TessLevelInner[0] = 1.0;\n"
233 			<< "        gl_TessLevelInner[1] = 1.0;\n"
234 			<< "        gl_TessLevelOuter[0] = 1.0;\n"
235 			<< "        gl_TessLevelOuter[1] = 1.0;\n"
236 			<< "        gl_TessLevelOuter[2] = 1.0;\n"
237 			<< "        gl_TessLevelOuter[3] = 1.0;\n"
238 			<< "    }\n"
239 			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
240 			<< "}\n";
241 		sources.glslSources.add("tsc") << glu::TessellationControlSource(tsc.str());
242 
243 		std::ostringstream tse;
244 		tse
245 			<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
246 			<< "layout (triangles, equal_spacing, cw) in;\n"
247 			<< "\n"
248 			<< "void main ()\n"
249 			<< "{\n"
250 			<< "    gl_Position = gl_in[0].gl_Position * gl_TessCoord.x +\n"
251 			<< "                  gl_in[1].gl_Position * gl_TessCoord.y +\n"
252 			<< "                  gl_in[2].gl_Position * gl_TessCoord.z;\n"
253 			<< "}\n"
254 			;
255 		sources.glslSources.add("tse") << glu::TessellationEvaluationSource(tse.str());
256 	}
257 
258 	std::ostringstream frag;
259 	frag
260 		<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
261 		<< "layout (location=0) out vec4 outColor;\n"
262 		<< "\n"
263 		<< "void main ()\n"
264 		<< "{\n"
265 		<< "    const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
266 		<< "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n"
267 		<< "    outColor = (gl_PrimitiveID % 2 == 0) ? red : green;\n"
268 		<< "}\n"
269 		;
270 	sources.glslSources.add("frag") << glu::FragmentSource(frag.str());
271 }
272 
iterate()273 tcu::TestStatus ImplicitPrimitiveIDPassthroughInstance::iterate ()
274 {
275 	const auto&			vkd					= m_context.getDeviceInterface();
276 	const auto			device				= m_context.getDevice();
277 	auto&				alloc				= m_context.getDefaultAllocator();
278 	const auto			qIndex				= m_context.getUniversalQueueFamilyIndex();
279 	const auto			queue				= m_context.getUniversalQueue();
280 	const auto			tcuFormat			= mapVkFormat(m_format);
281 	const auto			colorUsage			= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
282 	const auto			verifBufferUsage	= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
283 	const tcu::Vec4		clearColor			(0.0f, 0.0f, 0.0f, 1.0f);
284 
285 	// Color attachment.
286 	const VkImageCreateInfo colorBufferInfo =
287 	{
288 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
289 		nullptr,								//	const void*				pNext;
290 		0u,										//	VkImageCreateFlags		flags;
291 		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
292 		m_format,								//	VkFormat				format;
293 		m_extent,								//	VkExtent3D				extent;
294 		1u,										//	uint32_t				mipLevels;
295 		1u,										//	uint32_t				arrayLayers;
296 		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
297 		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
298 		colorUsage,								//	VkImageUsageFlags		usage;
299 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
300 		0u,										//	uint32_t				queueFamilyIndexCount;
301 		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
302 		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
303 	};
304 	ImageWithMemory		colorBuffer		(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
305 	const auto			colorSRR		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
306 	const auto			colorSRL		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
307 	const auto			colorBufferView	= makeImageView(vkd, device, colorBuffer.get(), VK_IMAGE_VIEW_TYPE_2D, m_format, colorSRR);
308 
309 	// Verification buffer.
310 	const auto			verifBufferSize		= static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * m_extent.width * m_extent.height;
311 	const auto			verifBufferInfo		= makeBufferCreateInfo(verifBufferSize, verifBufferUsage);
312 	BufferWithMemory	verifBuffer			(vkd, device, alloc, verifBufferInfo, MemoryRequirement::HostVisible);
313 	auto&				verifBufferAlloc	= verifBuffer.getAllocation();
314 
315 	// Render pass and framebuffer.
316 	RenderPassWrapper	renderPass			(m_pipelineConstructionType, vkd, device, m_format);
317 	renderPass.createFramebuffer(vkd, device, colorBuffer.get(), colorBufferView.get(), m_extent.width, m_extent.height);
318 
319 	// Shader modules.
320 	const auto&		binaries		= m_context.getBinaryCollection();
321 	const auto		vertModule		= ShaderWrapper(vkd, device, binaries.get("vert"));
322 	const auto		fragModule		= ShaderWrapper(vkd, device, binaries.get("frag"));
323 	ShaderWrapper tscModule;
324 	ShaderWrapper tseModule;
325 
326 	if (m_withTessellationPassthrough) {
327 		tscModule = ShaderWrapper(vkd, device, binaries.get("tsc"));
328 		tseModule = ShaderWrapper(vkd, device, binaries.get("tse"));
329 	}
330 
331 	// Viewports and scissors.
332 	const std::vector<VkViewport>	viewports	(1u, makeViewport(m_extent));
333 	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(m_extent));
334 
335 	const VkPipelineVertexInputStateCreateInfo		vertexInputState	= initVulkanStructure();
336 	const VkPipelineRasterizationStateCreateInfo    rasterizationState  =
337 	{
338 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
339 		DE_NULL,														// const void*                              pNext;
340 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
341 		VK_FALSE,														// VkBool32                                 depthClampEnable;
342 		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
343 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
344 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
345 		VK_FRONT_FACE_CLOCKWISE,								// VkFrontFace								frontFace;
346 		VK_FALSE,														// VkBool32									depthBiasEnable;
347 		0.0f,															// float									depthBiasConstantFactor;
348 		0.0f,															// float									depthBiasClamp;
349 		0.0f,															// float									depthBiasSlopeFactor;
350 		1.0f,															// float									lineWidth;
351 	};
352 
353 	// Pipeline layout and graphics pipeline.
354 	const PipelineLayoutWrapper pipelineLayout	(m_pipelineConstructionType, vkd, device);
355 
356 	const auto topology = m_withTessellationPassthrough ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
357 	m_graphicsPipeline.setDefaultRasterizationState()
358 		.setDefaultTopology(topology)
359 		.setupVertexInputState(&vertexInputState)
360 		.setDefaultDepthStencilState()
361 		.setDefaultMultisampleState()
362 		.setDefaultColorBlendState()
363 		.setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vertModule, &rasterizationState, tscModule, tseModule)
364 		.setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule)
365 		.setupFragmentOutputState(*renderPass)
366 		.setMonolithicPipelineLayout(pipelineLayout)
367 		.buildPipeline();
368 
369 	// Command pool and buffer.
370 	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
371 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
372 	const auto cmdBuffer	= cmdBufferPtr.get();
373 
374 	beginCommandBuffer(vkd, cmdBuffer);
375 
376 	// Draw.
377 	renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
378 	m_graphicsPipeline.bind(cmdBuffer);
379 	vkd.cmdDraw(cmdBuffer, 6, 1u, 0u, 0u);
380 	renderPass.end(vkd, cmdBuffer);
381 
382 	// Copy to verification buffer.
383 	const auto copyRegion		= makeBufferImageCopy(m_extent, colorSRL);
384 	const auto transfer2Host	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
385 	const auto color2Transfer	= makeImageMemoryBarrier(
386 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
387 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
388 		colorBuffer.get(), colorSRR);
389 
390 	cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &color2Transfer);
391 	vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verifBuffer.get(), 1u, &copyRegion);
392 	cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2Host);
393 
394 	endCommandBuffer(vkd, cmdBuffer);
395 
396 	// Submit and validate result.
397 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
398 
399 	auto& log = m_context.getTestContext().getLog();
400 	const tcu::IVec3					iExtent (static_cast<int>(m_extent.width), static_cast<int>(m_extent.height), static_cast<int>(m_extent.depth));
401 	void*								verifBufferData		= verifBufferAlloc.getHostPtr();
402 	const tcu::ConstPixelBufferAccess	verifAccess		(tcuFormat, iExtent, verifBufferData);
403 	invalidateAlloc(vkd, device, verifBufferAlloc);
404 
405 	const auto red = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
406 	const auto green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
407 
408 	for (int x = 0; x < iExtent.x(); ++x)
409 		for (int y = 0; y < iExtent.y(); ++y) {
410 			const auto resultColor = verifAccess.getPixel(x, y);
411 			const auto expectedColor = (x < iExtent.x() / 2) ? red : green;
412 			if (resultColor != expectedColor) {
413 				log << tcu::TestLog::ImageSet("Result image", "Expect left side of framebuffer red, and right side green")
414 					<< tcu::TestLog::Image("Result", "Verification buffer", verifAccess)
415 					<< tcu::TestLog::EndImageSet;
416 				TCU_FAIL("Expected a vertically split framebuffer, filled with red on the left and green the right; see the log for the unexpected result");
417 			}
418 		}
419 
420 	return tcu::TestStatus::pass("Pass");
421 }
422 
423 #ifndef CTS_USES_VULKANSC
424 struct UnusedShaderStageParams
425 {
426 	PipelineConstructionType	pipelineConstructionType;
427 	bool						useTessShaders;
428 	bool						useGeomShader;
429 };
430 
431 class UnusedShaderStagesCase : public vkt::TestCase
432 {
433 public:
UnusedShaderStagesCase(tcu::TestContext & testCtx,const std::string & name,const UnusedShaderStageParams & params)434 					UnusedShaderStagesCase	(tcu::TestContext& testCtx, const std::string& name, const UnusedShaderStageParams& params)
435 						: vkt::TestCase	(testCtx, name)
436 						, m_params		(params)
437 						{}
~UnusedShaderStagesCase(void)438 	virtual			~UnusedShaderStagesCase	(void) {}
439 
440 	void			initPrograms			(vk::SourceCollections& programCollection) const override;
441 	TestInstance*	createInstance			(Context& context) const override;
442 	void			checkSupport			(Context& context) const override;
443 
444 protected:
445 	UnusedShaderStageParams m_params;
446 };
447 
448 class UnusedShaderStagesInstance : public vkt::TestInstance
449 {
450 public:
UnusedShaderStagesInstance(Context & context,const UnusedShaderStageParams & params)451 						UnusedShaderStagesInstance	(Context& context, const UnusedShaderStageParams& params)
452 							: vkt::TestInstance	(context)
453 							, m_params			(params)
454 							{}
~UnusedShaderStagesInstance(void)455 	virtual				~UnusedShaderStagesInstance	(void) {}
456 	tcu::TestStatus		iterate						(void) override;
457 
458 protected:
459 	UnusedShaderStageParams m_params;
460 };
461 
initPrograms(vk::SourceCollections & programCollection) const462 void UnusedShaderStagesCase::initPrograms (vk::SourceCollections &programCollection) const
463 {
464 	// Shaders that produce bad results.
465 	{
466 		std::ostringstream vert;
467 		vert
468 			<< "#version 460\n"
469 			<< "out gl_PerVertex {\n"
470 			<< "    vec4 gl_Position;\n"
471 			<< "};\n"
472 			<< "void main (void) {\n"
473 			<< "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
474 			<< "}\n"
475 			;
476 		programCollection.glslSources.add("bad_vert") << glu::VertexSource(vert.str());
477 
478 		std::ostringstream tesc;
479 		tesc
480 			<< "#version 460\n"
481 			<< "layout (vertices=3) out;\n"
482 			<< "in gl_PerVertex {\n"
483 			<< "  vec4 gl_Position;\n"
484 			<< "} gl_in[gl_MaxPatchVertices];\n"
485 			<< "out gl_PerVertex {\n"
486 			<< "  vec4 gl_Position;\n"
487 			<< "} gl_out[];\n"
488 			<< "void main (void) {\n"
489 			<< "    gl_TessLevelInner[0] = 1.0;\n"
490 			<< "    gl_TessLevelInner[1] = 1.0;\n"
491 			<< "    gl_TessLevelOuter[0] = 1.0;\n"
492 			<< "    gl_TessLevelOuter[1] = 1.0;\n"
493 			<< "    gl_TessLevelOuter[2] = 1.0;\n"
494 			<< "    gl_TessLevelOuter[3] = 1.0;\n"
495 			<< "    gl_out[gl_InvocationID].gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
496 			<< "}\n"
497 			;
498 		programCollection.glslSources.add("bad_tesc") << glu::TessellationControlSource(tesc.str());
499 
500 		std::ostringstream tese;
501 		tese
502 			<< "#version 460\n"
503 			<< "layout (triangles, fractional_odd_spacing, cw) in;\n"
504 			<< "in gl_PerVertex {\n"
505 			<< "  vec4 gl_Position;\n"
506 			<< "} gl_in[gl_MaxPatchVertices];\n"
507 			<< "out gl_PerVertex {\n"
508 			<< "  vec4 gl_Position;\n"
509 			<< "};\n"
510 			<< "void main() {\n"
511 			<< "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
512 			<< "}\n"
513 			;
514 		programCollection.glslSources.add("bad_tese") << glu::TessellationEvaluationSource(tese.str());
515 
516 		std::ostringstream geom;
517 		geom
518 			<< "#version 460\n"
519 			<< "layout (triangles) in;\n"
520 			<< "layout (triangle_strip, max_vertices=3) out;\n"
521 			<< "in gl_PerVertex {\n"
522 			<< "    vec4 gl_Position;\n"
523 			<< "} gl_in[3];\n"
524 			<< "out gl_PerVertex {\n"
525 			<< "    vec4 gl_Position;\n"
526 			<< "};\n"
527 			<< "void main() {\n"
528 			// Avoid emitting any vertices.
529 			<< "}\n"
530 			;
531 		programCollection.glslSources.add("bad_geom") << glu::GeometrySource(geom.str());
532 
533 		std::ostringstream frag;
534 		frag
535 			<< "#version 460\n"
536 			<< "layout (location=0) out vec4 outColor;\n"
537 			<< "void main (void) {\n"
538 			<< "    outColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
539 			<< "}\n"
540 			;
541 		programCollection.glslSources.add("bad_frag") << glu::FragmentSource(frag.str());
542 	}
543 
544 	// Shaders that produce the expected results.
545 	{
546 		std::ostringstream vert;
547 		vert
548 			<< "#version 460\n"
549 			<< "out gl_PerVertex {\n"
550 			<< "    vec4 gl_Position;\n"
551 			<< "};\n"
552 			<< "vec2 positions[3] = vec2[](\n"
553 			<< "    vec2(-1.0, -1.0),\n"
554 			<< "    vec2(-1.0,  3.0),\n"
555 			<< "    vec2( 3.0, -1.0)\n"
556 			<< ");\n"
557 			<< "void main (void) {\n"
558 			<< "    gl_Position = vec4(positions[gl_VertexIndex % 3], 0.0, 1.0);\n"
559 			<< "}\n"
560 			;
561 		programCollection.glslSources.add("vert") << glu::VertexSource(vert.str());
562 
563 		std::ostringstream tesc;
564 		tesc
565 			<< "#version 460\n"
566 			<< "layout (vertices=3) out;\n"
567 			<< "in gl_PerVertex {\n"
568 			<< "  vec4 gl_Position;\n"
569 			<< "} gl_in[gl_MaxPatchVertices];\n"
570 			<< "out gl_PerVertex {\n"
571 			<< "  vec4 gl_Position;\n"
572 			<< "} gl_out[];\n"
573 			<< "void main (void) {\n"
574 			<< "    gl_TessLevelInner[0] = 1.0;\n"
575 			<< "    gl_TessLevelInner[1] = 1.0;\n"
576 			<< "    gl_TessLevelOuter[0] = 1.0;\n"
577 			<< "    gl_TessLevelOuter[1] = 1.0;\n"
578 			<< "    gl_TessLevelOuter[2] = 1.0;\n"
579 			<< "    gl_TessLevelOuter[3] = 1.0;\n"
580 			<< "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
581 			<< "}\n"
582 			;
583 		programCollection.glslSources.add("tesc") << glu::TessellationControlSource(tesc.str());
584 
585 		std::ostringstream tese;
586 		tese
587 			<< "#version 460\n"
588 			<< "layout (triangles, fractional_odd_spacing, cw) in;\n"
589 			<< "in gl_PerVertex {\n"
590 			<< "  vec4 gl_Position;\n"
591 			<< "} gl_in[gl_MaxPatchVertices];\n"
592 			<< "out gl_PerVertex {\n"
593 			<< "  vec4 gl_Position;\n"
594 			<< "};\n"
595 			<< "void main() {\n"
596 			<< "    gl_Position = (gl_TessCoord.x * gl_in[0].gl_Position) +\n"
597 			<< "                  (gl_TessCoord.y * gl_in[1].gl_Position) +\n"
598 			<< "                  (gl_TessCoord.z * gl_in[2].gl_Position);\n"
599 			<< "}\n"
600 			;
601 		programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(tese.str());
602 
603 		std::ostringstream geom;
604 		geom
605 			<< "#version 460\n"
606 			<< "layout (triangles) in;\n"
607 			<< "layout (triangle_strip, max_vertices=3) out;\n"
608 			<< "in gl_PerVertex {\n"
609 			<< "    vec4 gl_Position;\n"
610 			<< "} gl_in[3];\n"
611 			<< "out gl_PerVertex {\n"
612 			<< "    vec4 gl_Position;\n"
613 			<< "};\n"
614 			<< "void main() {\n"
615 			<< "    gl_Position = gl_in[0].gl_Position; EmitVertex();\n"
616 			<< "    gl_Position = gl_in[1].gl_Position; EmitVertex();\n"
617 			<< "    gl_Position = gl_in[2].gl_Position; EmitVertex();\n"
618 			<< "}\n"
619 			;
620 		programCollection.glslSources.add("geom") << glu::GeometrySource(geom.str());
621 
622 		std::ostringstream frag;
623 		frag
624 			<< "#version 460\n"
625 			<< "layout (location=0) out vec4 outColor;\n"
626 			<< "void main (void) {\n"
627 			<< "    outColor = vec4(0.0, 1.0, 0.0, 1.0);\n" // Blue instead of black.
628 			<< "}\n"
629 			;
630 		programCollection.glslSources.add("frag") << glu::FragmentSource(frag.str());
631 	}
632 }
633 
createInstance(Context & context) const634 TestInstance* UnusedShaderStagesCase::createInstance (Context &context) const
635 {
636 	return new UnusedShaderStagesInstance(context, m_params);
637 }
638 
checkSupport(Context & context) const639 void UnusedShaderStagesCase::checkSupport (Context &context) const
640 {
641 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
642 
643 	if (m_params.useTessShaders)
644 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_TESSELLATION_SHADER);
645 
646 	if (m_params.useGeomShader)
647 		context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_GEOMETRY_SHADER);
648 }
649 
iterate()650 tcu::TestStatus UnusedShaderStagesInstance::iterate ()
651 {
652 	const auto&			vkd				= m_context.getDeviceInterface();
653 	const auto			device			= m_context.getDevice();
654 	auto&				alloc			= m_context.getDefaultAllocator();
655 	const auto			queue			= m_context.getUniversalQueue();
656 	const auto			queueIndex		= m_context.getUniversalQueueFamilyIndex();
657 
658 	const bool			isOptimized		= (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY);
659 	const auto			colorExtent		= makeExtent3D(1u, 1u, 1u);
660 	const tcu::IVec3	colorExtentVec	(static_cast<int>(colorExtent.width), static_cast<int>(colorExtent.height), static_cast<int>(colorExtent.depth));
661 	const auto			colorFormat		= VK_FORMAT_R8G8B8A8_UNORM;
662 	const auto			colorUsage		= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
663 	const auto			colorSRR		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
664 	const auto			colorSRL		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
665 	const auto			tcuFormat		= mapVkFormat(colorFormat);
666 	const tcu::Vec4		clearColor		(0.0f, 0.0f, 0.0f, 0.0f);
667 	const tcu::Vec4		expectedColor	(0.0f, 1.0f, 0.0f, 1.0f); // Must match the good frag shader.
668 
669 	// Good and bad shader modules.
670 	const auto&	binaries			= m_context.getBinaryCollection();
671 
672 	const auto	goodVertModule		= createShaderModule(vkd, device, binaries.get("vert"));
673 	const auto	goodTescModule		= (m_params.useTessShaders ?	createShaderModule(vkd, device, binaries.get("tesc")) : Move<VkShaderModule>());
674 	const auto	goodTeseModule		= (m_params.useTessShaders ?	createShaderModule(vkd, device, binaries.get("tese")) : Move<VkShaderModule>());
675 	const auto	goodGeomModule		= (m_params.useGeomShader ?		createShaderModule(vkd, device, binaries.get("geom")) : Move<VkShaderModule>());
676 	const auto	goodFragModule		= createShaderModule(vkd, device, binaries.get("frag"));
677 
678 	const auto	goodVertShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, goodVertModule.get());
679 	const auto	goodTescShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, goodTescModule.get());
680 	const auto	goodTeseShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, goodTeseModule.get());
681 	const auto	goodGeomShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_GEOMETRY_BIT, goodGeomModule.get());
682 	const auto	goodFragShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, goodFragModule.get());
683 
684 	const auto	badVertModule		= createShaderModule(vkd, device, binaries.get("bad_vert"));
685 	const auto	badTescModule		= (m_params.useTessShaders ?	createShaderModule(vkd, device, binaries.get("bad_tesc")) : Move<VkShaderModule>());
686 	const auto	badTeseModule		= (m_params.useTessShaders ?	createShaderModule(vkd, device, binaries.get("bad_tese")) : Move<VkShaderModule>());
687 	const auto	badGeomModule		= (m_params.useGeomShader ?		createShaderModule(vkd, device, binaries.get("bad_geom")) : Move<VkShaderModule>());
688 	const auto	badFragModule		= createShaderModule(vkd, device, binaries.get("bad_frag"));
689 
690 	const auto	badVertShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_VERTEX_BIT, badVertModule.get());
691 	const auto	badTescShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, badTescModule.get());
692 	const auto	badTeseShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, badTeseModule.get());
693 	const auto	badGeomShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_GEOMETRY_BIT, badGeomModule.get());
694 	const auto	badFragShaderInfo	= makePipelineShaderStageCreateInfo(VK_SHADER_STAGE_FRAGMENT_BIT, badFragModule.get());
695 
696 	// Color attachment.
697 	const VkImageCreateInfo colorAttachmentCreateInfo =
698 	{
699 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
700 		nullptr,								//	const void*				pNext;
701 		0u,										//	VkImageCreateFlags		flags;
702 		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
703 		colorFormat,							//	VkFormat				format;
704 		colorExtent,							//	VkExtent3D				extent;
705 		1u,										//	uint32_t				mipLevels;
706 		1u,										//	uint32_t				arrayLayers;
707 		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
708 		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
709 		colorUsage,								//	VkImageUsageFlags		usage;
710 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
711 		0u,										//	uint32_t				queueFamilyIndexCount;
712 		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
713 		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
714 	};
715 	ImageWithMemory colorAttachment (vkd, device, alloc, colorAttachmentCreateInfo, MemoryRequirement::Any);
716 
717 	// Color attachment view.
718 	const auto colorAttachmentView = makeImageView(vkd, device, colorAttachment.get(), VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSRR);
719 
720 	// Verification buffer.
721 	const auto			verificationBufferSize			= static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * colorExtent.width * colorExtent.height * colorExtent.depth;
722 	const auto			verificationBufferCreateInfo	= makeBufferCreateInfo(verificationBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
723 	BufferWithMemory	verificationBuffer				(vkd, device, alloc, verificationBufferCreateInfo, MemoryRequirement::HostVisible);
724 	auto&				verificationBufferAlloc			= verificationBuffer.getAllocation();
725 
726 	// Render pass and framebuffer.
727 	RenderPassWrapper	renderPass						(m_params.pipelineConstructionType, vkd, device, colorFormat);
728 	renderPass.createFramebuffer(vkd, device, *colorAttachment, colorAttachmentView.get(), colorExtent.width, colorExtent.height);
729 
730 	// Pipeline layout.
731 	const auto pipelineLayout = makePipelineLayout(vkd, device);
732 
733 	// Pipeline state.
734 
735 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = initVulkanStructure();
736 
737 	const auto primitiveTopology = (m_params.useTessShaders ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
738 
739 	const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateInfo =
740 	{
741 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	//	VkStructureType							sType;
742 		nullptr,														//	const void*								pNext;
743 		0u,																//	VkPipelineInputAssemblyStateCreateFlags	flags;
744 		primitiveTopology,												//	VkPrimitiveTopology						topology;
745 		VK_FALSE,														//	VkBool32								primitiveRestartEnable;
746 	};
747 
748 	const VkPipelineTessellationStateCreateInfo tessellationStateInfo =
749 	{
750 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,	//	VkStructureType							sType;
751 		nullptr,													//	const void*								pNext;
752 		0u,															//	VkPipelineTessellationStateCreateFlags	flags;
753 		3u,															//	uint32_t								patchControlPoints;
754 	};
755 
756 	const std::vector<VkViewport>	viewports	(1u, makeViewport(colorExtent));
757 	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(colorExtent));
758 
759 	const VkPipelineViewportStateCreateInfo viewportStateInfo =
760 	{
761 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	//	VkStructureType						sType;
762 		nullptr,												//	const void*							pNext;
763 		0u,														//	VkPipelineViewportStateCreateFlags	flags;
764 		de::sizeU32(viewports),									//	uint32_t							viewportCount;
765 		de::dataOrNull(viewports),								//	const VkViewport*					pViewports;
766 		de::sizeU32(scissors),									//	uint32_t							scissorCount;
767 		de::dataOrNull(scissors),								//	const VkRect2D*						pScissors;
768 	};
769 
770 	const VkPipelineRasterizationStateCreateInfo rasterizationStateInfo =
771 	{
772 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		//	VkStructureType							sType;
773 		nullptr,														//	const void*								pNext;
774 		0u,																//	VkPipelineRasterizationStateCreateFlags	flags;
775 		VK_FALSE,														//	VkBool32								depthClampEnable;
776 		VK_FALSE,														//	VkBool32								rasterizerDiscardEnable;
777 		VK_POLYGON_MODE_FILL,											//	VkPolygonMode							polygonMode;
778 		VK_CULL_MODE_BACK_BIT,											//	VkCullModeFlags							cullMode;
779 		VK_FRONT_FACE_COUNTER_CLOCKWISE,								//	VkFrontFace								frontFace;
780 		VK_FALSE,														//	VkBool32								depthBiasEnable;
781 		0.0f,															//	float									depthBiasConstantFactor;
782 		0.0f,															//	float									depthBiasClamp;
783 		0.0f,															//	float									depthBiasSlopeFactor;
784 		1.0f,															//	float									lineWidth;
785 	};
786 
787 	const VkPipelineMultisampleStateCreateInfo multisampleStateInfo =
788 	{
789 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	//	VkStructureType							sType;
790 		nullptr,													//	const void*								pNext;
791 		0u,															//	VkPipelineMultisampleStateCreateFlags	flags;
792 		VK_SAMPLE_COUNT_1_BIT,										//	VkSampleCountFlagBits					rasterizationSamples;
793 		VK_FALSE,													//	VkBool32								sampleShadingEnable;
794 		1.0f,														//	float									minSampleShading;
795 		nullptr,													//	const VkSampleMask*						pSampleMask;
796 		VK_FALSE,													//	VkBool32								alphaToCoverageEnable;
797 		VK_FALSE,													//	VkBool32								alphaToOneEnable;
798 	};
799 
800 	const VkPipelineDepthStencilStateCreateInfo depthStencilStateInfo = initVulkanStructure();
801 
802 	const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
803 
804 	const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
805 	{
806 		VK_FALSE,				//	VkBool32				blendEnable;
807 		VK_BLEND_FACTOR_ZERO,	//	VkBlendFactor			srcColorBlendFactor;
808 		VK_BLEND_FACTOR_ZERO,	//	VkBlendFactor			dstColorBlendFactor;
809 		VK_BLEND_OP_ADD,		//	VkBlendOp				colorBlendOp;
810 		VK_BLEND_FACTOR_ZERO,	//	VkBlendFactor			srcAlphaBlendFactor;
811 		VK_BLEND_FACTOR_ZERO,	//	VkBlendFactor			dstAlphaBlendFactor;
812 		VK_BLEND_OP_ADD,		//	VkBlendOp				alphaBlendOp;
813 		colorComponentFlags,	//	VkColorComponentFlags	colorWriteMask;
814 	};
815 
816 	const VkPipelineColorBlendStateCreateInfo colorBlendStateInfo =
817 	{
818 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	//	VkStructureType								sType;
819 		nullptr,													//	const void*									pNext;
820 		0u,															//	VkPipelineColorBlendStateCreateFlags		flags;
821 		VK_FALSE,													//	VkBool32									logicOpEnable;
822 		VK_LOGIC_OP_CLEAR,											//	VkLogicOp									logicOp;
823 		1u,															//	uint32_t									attachmentCount;
824 		&colorBlendAttachmentState,									//	const VkPipelineColorBlendAttachmentState*	pAttachments;
825 		{ 0.0f, 0.0f, 0.0f, 0.0f },									//	float										blendConstants[4];
826 	};
827 
828 	// Make a few vectors with the wrong shader modules.
829 	std::vector<VkPipelineShaderStageCreateInfo> badPreRasterStages;
830 	badPreRasterStages.push_back(badVertShaderInfo);
831 	if (m_params.useTessShaders)
832 	{
833 		badPreRasterStages.push_back(badTescShaderInfo);
834 		badPreRasterStages.push_back(badTeseShaderInfo);
835 	}
836 	if (m_params.useGeomShader)
837 		badPreRasterStages.push_back(badGeomShaderInfo);
838 
839 	std::vector<VkPipelineShaderStageCreateInfo> allBadStages (badPreRasterStages);
840 	allBadStages.push_back(badFragShaderInfo);
841 
842 	// Make a few vectors with the right shader modules.
843 	std::vector<VkPipelineShaderStageCreateInfo> goodPreRasterStages;
844 	goodPreRasterStages.push_back(goodVertShaderInfo);
845 	if (m_params.useTessShaders)
846 	{
847 		goodPreRasterStages.push_back(goodTescShaderInfo);
848 		goodPreRasterStages.push_back(goodTeseShaderInfo);
849 	}
850 	if (m_params.useGeomShader)
851 		goodPreRasterStages.push_back(goodGeomShaderInfo);
852 
853 	std::vector<VkPipelineShaderStageCreateInfo> allGoodStages (goodPreRasterStages);
854 	allGoodStages.push_back(goodFragShaderInfo);
855 
856 	// Build the different pipeline pieces.
857 	Move<VkPipeline> vertexInputLib;
858 	Move<VkPipeline> preRasterShaderLib;
859 	Move<VkPipeline> fragShaderLib;
860 	Move<VkPipeline> fragOutputLib;
861 
862 	VkPipelineCreateFlags libCreationFlags	= VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
863 	VkPipelineCreateFlags linkFlags			= 0u;
864 
865 	if (isOptimized)
866 	{
867 		libCreationFlags	|= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
868 		linkFlags			|= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
869 	}
870 
871 	// Vertex input state library.
872 	{
873 		VkGraphicsPipelineLibraryCreateInfoEXT vertexInputLibInfo	= initVulkanStructure();
874 		vertexInputLibInfo.flags									|= VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT;
875 
876 		VkGraphicsPipelineCreateInfo vertexInputPipelineInfo	= initVulkanStructure(&vertexInputLibInfo);
877 		vertexInputPipelineInfo.flags							= libCreationFlags;
878 		vertexInputPipelineInfo.pVertexInputState				= &vertexInputStateInfo;
879 		vertexInputPipelineInfo.pInputAssemblyState				= &inputAssemblyStateInfo;
880 
881 		// Add all bad shaders (they should be ignored).
882 		vertexInputPipelineInfo.stageCount	= de::sizeU32(allBadStages);
883 		vertexInputPipelineInfo.pStages		= de::dataOrNull(allBadStages);
884 
885 		vertexInputLib = createGraphicsPipeline(vkd, device, DE_NULL, &vertexInputPipelineInfo);
886 	}
887 
888 	// Pre-rasterization shader state library.
889 	{
890 		VkGraphicsPipelineLibraryCreateInfoEXT preRasterShaderLibInfo	= initVulkanStructure();
891 		preRasterShaderLibInfo.flags									|= VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
892 
893 		VkGraphicsPipelineCreateInfo preRasterShaderPipelineInfo	= initVulkanStructure(&preRasterShaderLibInfo);
894 		preRasterShaderPipelineInfo.flags							= libCreationFlags;
895 		preRasterShaderPipelineInfo.layout							= pipelineLayout.get();
896 		preRasterShaderPipelineInfo.pViewportState					= &viewportStateInfo;
897 		preRasterShaderPipelineInfo.pRasterizationState				= &rasterizationStateInfo;
898 		if (m_params.useTessShaders)
899 		{
900 			preRasterShaderPipelineInfo.pInputAssemblyState			= &inputAssemblyStateInfo;
901 			preRasterShaderPipelineInfo.pTessellationState			= &tessellationStateInfo;
902 		}
903 		preRasterShaderPipelineInfo.renderPass						= renderPass.get();
904 
905 		// All good pre-rasterization stages.
906 		auto preRasterStagesVec = goodPreRasterStages;
907 		// The bad fragment shader state cannot be added here due to VUID-VkGraphicsPipelineCreateInfo-pStages-06894.
908 		//preRasterStagesVec.push_back(badFragShaderInfo);
909 
910 		preRasterShaderPipelineInfo.stageCount	= de::sizeU32(preRasterStagesVec);
911 		preRasterShaderPipelineInfo.pStages		= de::dataOrNull(preRasterStagesVec);
912 
913 		preRasterShaderLib = createGraphicsPipeline(vkd, device, DE_NULL, &preRasterShaderPipelineInfo);
914 	}
915 
916 	// Fragment shader stage library.
917 	{
918 		VkGraphicsPipelineLibraryCreateInfoEXT fragShaderLibInfo	= initVulkanStructure();
919 		fragShaderLibInfo.flags										|= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
920 
921 		VkGraphicsPipelineCreateInfo fragShaderPipelineInfo	= initVulkanStructure(&fragShaderLibInfo);
922 		fragShaderPipelineInfo.flags						= libCreationFlags;
923 		fragShaderPipelineInfo.layout						= pipelineLayout.get();
924 		fragShaderPipelineInfo.pMultisampleState			= &multisampleStateInfo;
925 		fragShaderPipelineInfo.pDepthStencilState			= &depthStencilStateInfo;
926 		fragShaderPipelineInfo.renderPass					= renderPass.get();
927 
928 		// The good fragment shader stage.
929 		std::vector<VkPipelineShaderStageCreateInfo> fragShaderStagesVec;
930 		// We cannot add the bad pre-rasterization shader stages due to VUID-VkGraphicsPipelineCreateInfo-pStages-06895.
931 		//fragShaderStagesVec.insert(fragShaderStagesVec.end(), badPreRasterStages.begin(), badPreRasterStages.end())
932 		fragShaderStagesVec.push_back(goodFragShaderInfo);
933 
934 		fragShaderPipelineInfo.stageCount	= de::sizeU32(fragShaderStagesVec);
935 		fragShaderPipelineInfo.pStages		= de::dataOrNull(fragShaderStagesVec);
936 
937 		fragShaderLib = createGraphicsPipeline(vkd, device, DE_NULL, &fragShaderPipelineInfo);
938 	}
939 
940 	// Fragment output library.
941 	{
942 		VkGraphicsPipelineLibraryCreateInfoEXT fragOutputLibInfo	= initVulkanStructure();
943 		fragOutputLibInfo.flags										|= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT;
944 
945 		VkGraphicsPipelineCreateInfo fragOutputPipelineInfo	= initVulkanStructure(&fragOutputLibInfo);
946 		fragOutputPipelineInfo.flags						= libCreationFlags;
947 		fragOutputPipelineInfo.pColorBlendState				= &colorBlendStateInfo;
948 		fragOutputPipelineInfo.renderPass					= renderPass.get();
949 		fragOutputPipelineInfo.pMultisampleState			= &multisampleStateInfo;
950 
951 		// Add all bad shaders (they should be ignored).
952 		fragOutputPipelineInfo.stageCount	= de::sizeU32(allBadStages);
953 		fragOutputPipelineInfo.pStages		= de::dataOrNull(allBadStages);
954 
955 		fragOutputLib = createGraphicsPipeline(vkd, device, DE_NULL, &fragOutputPipelineInfo);
956 	}
957 
958 	// Linked pipeline.
959 	const std::vector<VkPipeline> libraryHandles
960 	{
961 		vertexInputLib.get(),
962 		preRasterShaderLib.get(),
963 		fragShaderLib.get(),
964 		fragOutputLib.get(),
965 	};
966 
967 	VkPipelineLibraryCreateInfoKHR linkedPipelineLibraryInfo	= initVulkanStructure();
968 	linkedPipelineLibraryInfo.libraryCount						= de::sizeU32(libraryHandles);
969 	linkedPipelineLibraryInfo.pLibraries						= de::dataOrNull(libraryHandles);
970 
971 	VkGraphicsPipelineCreateInfo linkedPipelineInfo	= initVulkanStructure(&linkedPipelineLibraryInfo);
972 	linkedPipelineInfo.flags						= linkFlags;
973 	linkedPipelineInfo.layout						= pipelineLayout.get();
974 	linkedPipelineInfo.stageCount					= de::sizeU32(allBadStages);
975 	linkedPipelineInfo.pStages						= de::dataOrNull(allBadStages);
976 
977 	const auto pipeline = createGraphicsPipeline(vkd, device, DE_NULL, &linkedPipelineInfo);
978 
979 	// Command pool, command buffer and draw.
980 	const auto cmdPool		= makeCommandPool(vkd, device, queueIndex);
981 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
982 	const auto cmdBuffer	= cmdBufferPtr.get();
983 
984 	beginCommandBuffer(vkd, cmdBuffer);
985 	renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
986 	vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.get());
987 	vkd.cmdDraw(cmdBuffer, 3u, 1u, 0u, 0u);
988 	renderPass.end(vkd, cmdBuffer);
989 
990 	// Copy color attachment to verification buffer.
991 	const auto preCopyBarrier	= makeImageMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
992 														 VK_ACCESS_TRANSFER_READ_BIT,
993 														 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
994 														 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
995 														 colorAttachment.get(), colorSRR);
996 	const auto copyRegion		= makeBufferImageCopy(colorExtent, colorSRL);
997 	const auto postCopyBarrier	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
998 
999 	cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &preCopyBarrier);
1000 	vkd.cmdCopyImageToBuffer(cmdBuffer, colorAttachment.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verificationBuffer.get(), 1u, &copyRegion);
1001 	cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &postCopyBarrier);
1002 
1003 	endCommandBuffer(vkd, cmdBuffer);
1004 
1005 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1006 
1007 	// Verify pixel contents.
1008 	invalidateAlloc(vkd, device, verificationBufferAlloc);
1009 	tcu::PixelBufferAccess resultAccess (tcuFormat, colorExtentVec, verificationBufferAlloc.getHostPtr());
1010 
1011 	for (int z = 0; z < colorExtentVec.z(); ++z)
1012 		for (int y = 0; y < colorExtentVec.y(); ++y)
1013 			for (int x = 0; x < colorExtentVec.x(); ++x)
1014 			{
1015 				const auto resultColor = resultAccess.getPixel(x, y, z);
1016 				if (resultColor != expectedColor)
1017 				{
1018 					const tcu::IVec3 position(x, y, z);
1019 					std::ostringstream msg;
1020 					msg << "Bad color found at pixel " << position << ": expected " << expectedColor << " but found " << resultColor;
1021 					TCU_FAIL(msg.str());
1022 				}
1023 			}
1024 
1025 	return tcu::TestStatus::pass("Pass");
1026 }
1027 #endif // CTS_USES_VULKANSC
1028 
1029 #ifndef CTS_USES_VULKANSC
1030 class PipelineLibraryInterpolateAtSampleTestCase : public vkt::TestCase
1031 {
1032 public:
1033 	PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext& context, const std::string& name);
1034 	void            initPrograms            (vk::SourceCollections& programCollection) const override;
1035 	TestInstance*   createInstance          (Context& context) const override;
1036 	void            checkSupport            (Context& context) const override;
1037 	//there are 4 sample points, which may have a shader invocation each, each of them writes 5 values
1038 	//and we render a 2x2 grid.
1039 	static constexpr uint32_t				width		= 2;
1040 	static constexpr uint32_t				height		= 2;
1041 	static constexpr VkSampleCountFlagBits	sampleCount = VK_SAMPLE_COUNT_4_BIT;
1042 	static constexpr uint32_t ResultCount = (sampleCount + 1) * sampleCount * width * height;
1043 };
1044 
1045 class PipelineLibraryInterpolateAtSampleTestInstance : public vkt::TestInstance
1046 {
1047 public:
1048 	PipelineLibraryInterpolateAtSampleTestInstance(Context& context);
1049 	void runTest(BufferWithMemory& index, BufferWithMemory& values, size_t bufferSize, PipelineConstructionType type);
1050 	virtual tcu::TestStatus iterate(void);
1051 };
1052 
PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext & context,const std::string & name)1053 PipelineLibraryInterpolateAtSampleTestCase::PipelineLibraryInterpolateAtSampleTestCase(tcu::TestContext& context, const std::string& name):
1054 	vkt::TestCase(context, name) { }
1055 
checkSupport(Context & context) const1056 void PipelineLibraryInterpolateAtSampleTestCase::checkSupport(Context& context) const
1057 {
1058 	context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
1059 	context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_FRAGMENT_STORES_AND_ATOMICS);
1060 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY);
1061 }
1062 
initPrograms(vk::SourceCollections & collection) const1063 void PipelineLibraryInterpolateAtSampleTestCase::initPrograms(vk::SourceCollections& collection) const
1064 {
1065 	{
1066 		std::ostringstream src;
1067 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1068 		<< "vec2 positions[6] = vec2[](\n"
1069 		<< "		vec2(1.0, 1.0),"
1070 		<< "		vec2(-1.0, 1.0),"
1071 		<< "		vec2(-1.0, -1.0),"
1072 		<< "		vec2(-1.0, -1.0),"
1073 		<< "		vec2(1.0, -1.0),"
1074 		<< "		vec2(1.0, 1.0)"
1075 		<< ");\n"
1076 		<< "float values[6] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6};\n"
1077 		<< "layout (location=0) out float verify;"
1078 		<< "void main() {\n"
1079 		<< "		gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);\n"
1080 		<< "		verify = values[gl_VertexIndex];\n"
1081 		<< "}";
1082 		collection.glslSources.add("vert") << glu::VertexSource(src.str());
1083 	}
1084 
1085 	{
1086 		std::ostringstream src;
1087 		src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1088 		<< "layout(location = 0) out vec4 outColor;\n"
1089 		<< "layout (location=0) in float verify;"
1090 		<< "layout(std430, binding = 0) buffer Index {"
1091 		<< "	uint writeIndex;"
1092 		<< "} index;\n"
1093 		<< "layout(std430, binding = 1) buffer Values {"
1094 		<< "	float num[" << PipelineLibraryInterpolateAtSampleTestCase::ResultCount << "];"
1095 		<< "} values;\n"
1096 		<< "void main() {\n"
1097 		<< "	uint index = atomicAdd(index.writeIndex, 5);"
1098 		<< "	float iSample1 = interpolateAtSample(verify, 0);\n"
1099 		<< "	float iSample2 = interpolateAtSample(verify, 1);\n"
1100 		<< "	float iSample3 = interpolateAtSample(verify, 2);\n"
1101 		<< "	float iSample4 = interpolateAtSample(verify, 3);\n"
1102 		<< "	values.num[index] = verify;"
1103 		<< "	values.num[index + 1] = iSample1;"
1104 		<< "	values.num[index + 2] = iSample2;"
1105 		<< "	values.num[index + 3] = iSample3;"
1106 		<< "	values.num[index + 4] = iSample4;"
1107 		<< "	outColor = vec4(1.0, 1.0, 0.0, 1.0);\n"
1108 		<< "}";
1109 		collection.glslSources.add("frag") << glu::FragmentSource(src.str());
1110 	}
1111 }
1112 
createInstance(Context & context) const1113 TestInstance* PipelineLibraryInterpolateAtSampleTestCase::createInstance(Context& context) const
1114 {
1115 	return new PipelineLibraryInterpolateAtSampleTestInstance(context);
1116 }
1117 
PipelineLibraryInterpolateAtSampleTestInstance(Context & context)1118 PipelineLibraryInterpolateAtSampleTestInstance::PipelineLibraryInterpolateAtSampleTestInstance(Context& context) : vkt::TestInstance(context) { }
1119 
runTest(BufferWithMemory & index,BufferWithMemory & values,size_t bufferSize,PipelineConstructionType type)1120 void PipelineLibraryInterpolateAtSampleTestInstance::runTest(BufferWithMemory& index, BufferWithMemory& values, size_t bufferSize, PipelineConstructionType type)
1121 {
1122 	const auto& vki			= m_context.getInstanceInterface();
1123 	const auto& vkd			= m_context.getDeviceInterface();
1124 	const auto  physDevice	= m_context.getPhysicalDevice();
1125 	const auto  device		= m_context.getDevice();
1126 	auto& alloc				= m_context.getDefaultAllocator();
1127 	auto imageFormat		= vk::VK_FORMAT_R8G8B8A8_UNORM;
1128 	auto imageExtent		= vk::makeExtent3D(2, 2, 1u);
1129 
1130 	const std::vector<vk::VkViewport>	viewports	{ makeViewport(imageExtent) };
1131 	const std::vector<vk::VkRect2D>		scissors	{ makeRect2D(imageExtent) };
1132 
1133 	de::MovePtr<vk::ImageWithMemory>  colorAttachment;
1134 
1135 	vk::GraphicsPipelineWrapper pipeline1(vki, vkd, physDevice, device, m_context.getDeviceExtensions(), type);
1136 	const auto  qIndex	= m_context.getUniversalQueueFamilyIndex();
1137 
1138 	const auto  subresourceRange	= vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1139 	const auto  imageUsage			= static_cast<vk::VkImageUsageFlags>(vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1140 	const vk::VkImageCreateInfo imageCreateInfo =
1141 	{
1142 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType				sType;
1143 		nullptr,									//	const void*					pNext;
1144 		0u,											//	VkImageCreateFlags			flags;
1145 		vk::VK_IMAGE_TYPE_2D,						//	VkImageType					imageType;
1146 		imageFormat,								//	VkFormat					format;
1147 		imageExtent,								//	VkExtent3D					extent;
1148 		1u,											//	deUint32					mipLevels;
1149 		1u,											//	deUint32					arrayLayers;
1150 		vk::VK_SAMPLE_COUNT_4_BIT,					//	VkSampleCountFlagBits		samples;
1151 		vk::VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling				tiling;
1152 		imageUsage,									//	VkImageUsageFlags			usage;
1153 		vk::VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode				sharingMode;
1154 		1u,											//	deUint32					queueFamilyIndexCount;
1155 		&qIndex,									//	const deUint32*				pQueueFamilyIndices;
1156 		vk::VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout				initialLayout;
1157 	};
1158 
1159 	colorAttachment               = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vkd, device, alloc, imageCreateInfo, vk::MemoryRequirement::Any));
1160 	auto colorAttachmentView      = vk::makeImageView(vkd, device, colorAttachment->get(), vk::VK_IMAGE_VIEW_TYPE_2D, imageFormat, subresourceRange);
1161 
1162 	vk::DescriptorSetLayoutBuilder layoutBuilder;
1163 	layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1164 	layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1165 
1166 	auto descriptorSetLayout    = layoutBuilder.build(vkd, device);
1167 	vk::PipelineLayoutWrapper	graphicsPipelineLayout (type, vkd, device, descriptorSetLayout.get());
1168 
1169 	DescriptorPoolBuilder poolBuilder;
1170 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1171 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
1172 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1173 	const auto descriptorSetBuffer		= makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
1174 
1175 	// Update descriptor sets.
1176 	DescriptorSetUpdateBuilder updater;
1177 
1178 	const auto indexBufferInfo = makeDescriptorBufferInfo(index.get(), 0ull, sizeof(uint32_t));
1179 	const auto valueBufferInfo = makeDescriptorBufferInfo(values.get(), 0ull, bufferSize);
1180 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &indexBufferInfo);
1181 	updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &valueBufferInfo);
1182 
1183 	updater.update(vkd, device);
1184 
1185 	auto vtxshader  = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("vert"));
1186 	auto frgshader  = ShaderWrapper(vkd, device, m_context.getBinaryCollection().get("frag"));
1187 
1188 	const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
1189 	{
1190 		vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType sType
1191 		nullptr,														// const void*                                 pNext
1192 		0u,																// VkPipelineVertexInputStateCreateFlags       flags
1193 		0u,																// deUint32                                    vertexBindingDescriptionCount
1194 		nullptr,														// const VkVertexInputBindingDescription*      pVertexBindingDescriptions
1195 		0u,																// deUint32                                    vertexAttributeDescriptionCount
1196 		nullptr,														// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions
1197 	};
1198 
1199 	VkPipelineMultisampleStateCreateInfo multisampling = initVulkanStructure();
1200 	multisampling.sampleShadingEnable = VK_FALSE;
1201 	multisampling.rasterizationSamples = VK_SAMPLE_COUNT_4_BIT;
1202 	multisampling.minSampleShading = 1.0f; // Optional
1203 	multisampling.pSampleMask = NULL; // Optional
1204 	multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
1205 	multisampling.alphaToOneEnable = VK_FALSE; // Optional
1206 
1207 	pipeline1.setDefaultTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST)
1208 		.setDefaultRasterizationState()
1209 		.setDefaultDepthStencilState()
1210 		.setDefaultColorBlendState()
1211 		.setupVertexInputState(&vertexInputState)
1212 		.setupPreRasterizationShaderState(
1213 			viewports,
1214 			scissors,
1215 			graphicsPipelineLayout,
1216 			DE_NULL,
1217 			0u,
1218 			vtxshader)
1219 		.setupFragmentShaderState(graphicsPipelineLayout, DE_NULL, 0u,
1220 			frgshader)
1221 		.setupFragmentOutputState(DE_NULL, 0u, DE_NULL, &multisampling)
1222 		.setMonolithicPipelineLayout(graphicsPipelineLayout).buildPipeline();
1223 
1224 	auto commandPool = createCommandPool(vkd, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, qIndex);
1225 	auto commandBuffer = vk::allocateCommandBuffer(vkd, device, commandPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1226 
1227 	const auto		clearValueColor		= vk::makeClearValueColor(tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
1228 
1229 	const vk::VkRect2D renderArea =
1230 	{
1231 		{ 0u, 0u },
1232 		{ imageExtent.width, imageExtent.height }
1233 	};
1234 
1235 	const vk::VkRenderingAttachmentInfoKHR colorAttachments = {
1236 		vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR,	// VkStructureType						sType;
1237 		DE_NULL,												// const void*							pNext;
1238 		colorAttachmentView.get(),								// VkImageView							imageView;
1239 		vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,				// VkImageLayout						imageLayout;
1240 		vk::VK_RESOLVE_MODE_NONE,								// VkResolveModeFlagBits				resolveMode;
1241 		DE_NULL,												// VkImageView							resolveImageView;
1242 		vk::VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,				// VkImageLayout						resolveImageLayout;
1243 		vk::VK_ATTACHMENT_LOAD_OP_CLEAR,						// VkAttachmentLoadOp					loadOp;
1244 		vk::VK_ATTACHMENT_STORE_OP_STORE,						// VkAttachmentStoreOp					storeOp;
1245 		clearValueColor											// VkClearValue							clearValue;
1246 	};
1247 	const VkRenderingInfoKHR render_info = {
1248 		VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
1249 		0,
1250 		0,
1251 		renderArea,
1252 		1,
1253 		0,
1254 		1,
1255 		&colorAttachments,
1256 		DE_NULL,
1257 		DE_NULL
1258 	};
1259 
1260 	vk::beginCommandBuffer(vkd, commandBuffer.get());
1261 	vk::VkImageMemoryBarrier initialBarrier = makeImageMemoryBarrier(0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR,
1262 		(*colorAttachment).get(), subresourceRange);
1263 	vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0, nullptr,
1264 						  0, nullptr, 1, &initialBarrier);
1265 	vkd.cmdBindDescriptorSets(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipelineLayout.get(), 0u, 1, &descriptorSetBuffer.get(), 0u, nullptr);
1266 
1267 	vkd.cmdBeginRendering(*commandBuffer, &render_info);
1268 	pipeline1.bind(commandBuffer.get());
1269 	vkd.cmdSetPatchControlPointsEXT(commandBuffer.get(), 3);
1270 	vkd.cmdDraw(commandBuffer.get(), 6, 1, 0, 0);
1271 	vkd.cmdEndRendering(*commandBuffer);
1272 
1273 	const VkBufferMemoryBarrier indexBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, index.get(), 0ull, sizeof(uint32_t));
1274 	vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1275 		0u, 0, nullptr, 1, &indexBufferBarrier, 0, nullptr);
1276 
1277 	const VkBufferMemoryBarrier valueBufferBarrier = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, values.get(), 0ull, bufferSize);
1278 	vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1279 		0u, 0, nullptr, 1, &valueBufferBarrier, 0, nullptr);
1280 
1281 	vk::endCommandBuffer(vkd, commandBuffer.get());
1282 	vk::submitCommandsAndWait(vkd, device, m_context.getUniversalQueue(), commandBuffer.get());
1283 }
1284 
iterate(void)1285 tcu::TestStatus PipelineLibraryInterpolateAtSampleTestInstance::iterate(void)
1286 {
1287 	const auto& vkd			= m_context.getDeviceInterface();
1288 	const auto  device		= m_context.getDevice();
1289 	auto& alloc				= m_context.getDefaultAllocator();
1290 
1291 	struct ValueBuffer {
1292 		float values[PipelineLibraryInterpolateAtSampleTestCase::ResultCount];
1293 	};
1294 
1295 	size_t resultSize = PipelineLibraryInterpolateAtSampleTestCase::ResultCount;
1296 
1297 	const auto			indexBufferSize	= static_cast<VkDeviceSize>(sizeof(uint32_t));
1298 	const auto			valueBufferSize	= static_cast<VkDeviceSize>(sizeof(ValueBuffer));
1299 
1300 	auto indexCreateInfo	= makeBufferCreateInfo(indexBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1301 	auto valuesCreateInfo	= makeBufferCreateInfo(valueBufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1302 
1303 	BufferWithMemory	indexBufferMonolithic		(vkd, device, alloc, indexCreateInfo, MemoryRequirement::HostVisible);
1304 	BufferWithMemory	valuesBufferMonolithic		(vkd, device, alloc, valuesCreateInfo, MemoryRequirement::HostVisible);
1305 	BufferWithMemory	indexBufferGPL				(vkd, device, alloc, indexCreateInfo, MemoryRequirement::HostVisible);
1306 	BufferWithMemory	valuesBufferGPL				(vkd, device, alloc, valuesCreateInfo, MemoryRequirement::HostVisible);
1307 
1308 	auto&				indexBufferMonolithicAlloc	= indexBufferMonolithic.getAllocation();
1309 	auto&				valuesBufferMonolithicAlloc	= valuesBufferMonolithic.getAllocation();
1310 	auto&				indexBufferGPLAlloc	= indexBufferGPL.getAllocation();
1311 	auto&				valuesBufferGPLAlloc	= valuesBufferGPL.getAllocation();
1312 
1313 	void*				indexBufferMonolithicData	= indexBufferMonolithicAlloc.getHostPtr();
1314 	void*				valuesBufferMonolithicData	= valuesBufferMonolithicAlloc.getHostPtr();
1315 	void*				indexBufferGPLData	= indexBufferGPLAlloc.getHostPtr();
1316 	void*				valuesBufferGPLData	= valuesBufferGPLAlloc.getHostPtr();
1317 
1318 	deMemset(indexBufferMonolithicData, 0, sizeof(uint32_t));
1319 	deMemset(valuesBufferMonolithicData, 0, sizeof(ValueBuffer));
1320 	deMemset(indexBufferGPLData, 0, sizeof(uint32_t));
1321 	deMemset(valuesBufferGPLData, 0, sizeof(ValueBuffer));
1322 
1323 	flushAlloc(vkd, device, indexBufferMonolithicAlloc);
1324 	flushAlloc(vkd, device, valuesBufferMonolithicAlloc);
1325 	flushAlloc(vkd, device, indexBufferGPLAlloc);
1326 	flushAlloc(vkd, device, valuesBufferGPLAlloc);
1327 
1328 	runTest(indexBufferMonolithic, valuesBufferMonolithic, valueBufferSize, vk::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC);
1329 	runTest(indexBufferGPL, valuesBufferGPL, valueBufferSize, vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY);
1330 
1331 	invalidateAlloc(vkd, device, indexBufferMonolithicAlloc);
1332 	invalidateAlloc(vkd, device, valuesBufferMonolithicAlloc);
1333 	invalidateAlloc(vkd, device, indexBufferGPLAlloc);
1334 	invalidateAlloc(vkd, device, valuesBufferGPLAlloc);
1335 
1336 	uint32_t monolithicIndex;
1337 	uint32_t GPLIndex;
1338 	struct ValueBuffer monolithicResult		= ValueBuffer();
1339 	struct ValueBuffer GPLResult			= ValueBuffer();
1340 	memcpy((void*)&monolithicIndex, indexBufferMonolithicData, sizeof(uint32_t));
1341 	memcpy((void*)&GPLIndex, indexBufferGPLData, sizeof(uint32_t));
1342 	memcpy((void*)&monolithicResult, valuesBufferMonolithicData, sizeof(ValueBuffer));
1343 	memcpy((void*)&GPLResult, valuesBufferGPLData, sizeof(ValueBuffer));
1344 
1345 	//we can't know which order the shaders will run in
1346 	std::sort(monolithicResult.values, monolithicResult.values + resultSize);
1347 	std::sort(GPLResult.values, GPLResult.values + resultSize);
1348 
1349 	//check that the atomic counters are at enough for the number of invocations
1350 	constexpr int expected = (PipelineLibraryInterpolateAtSampleTestCase::sampleCount + 1) *
1351 		PipelineLibraryInterpolateAtSampleTestCase::width * PipelineLibraryInterpolateAtSampleTestCase::height;
1352 
1353 	if (monolithicIndex < expected && GPLIndex < expected) {
1354 			return tcu::TestStatus::fail("Atomic counter value lower than expected");
1355 	}
1356 
1357 	for (uint32_t i = 1; i < PipelineLibraryInterpolateAtSampleTestCase::ResultCount; i++) {
1358 		if (monolithicResult.values[i] != monolithicResult.values[i]) {
1359 			return tcu::TestStatus::fail("Comparison failed");
1360 		}
1361 	}
1362 
1363 	return tcu::TestStatus::pass("Pass");
1364 }
1365 #endif
1366 
1367 struct BindingTestConfig {
1368 	PipelineConstructionType construction;
1369 	bool backwardsBinding;
1370 	bool holes;
1371 };
1372 
1373 /*
1374  * Test the following behaviours:
1375  * Descriptor sets updated/bound in backwards order
1376  * Descriptor sets with index holes updated/bound/used
1377  */
1378 class PipelineLayoutBindingTestCases : public vkt::TestCase
1379 {
1380 public:
PipelineLayoutBindingTestCases(tcu::TestContext & testCtx,const std::string & name,const BindingTestConfig & config)1381 	PipelineLayoutBindingTestCases		(tcu::TestContext&                  testCtx,
1382 											 const std::string&                 name,
1383 											 const BindingTestConfig&			config)
1384 		: vkt::TestCase(testCtx, name)
1385 		, m_config(config)
1386 	{
1387 	}
~PipelineLayoutBindingTestCases(void)1388 	~PipelineLayoutBindingTestCases		    (void) {}
1389 	void			initPrograms				(SourceCollections& programCollection) const override;
1390 	void			checkSupport				(Context& context) const override;
1391 	TestInstance*	createInstance				(Context& context) const override;
1392 
1393 	const BindingTestConfig m_config;
1394 };
1395 
1396 class PipelineLayoutBindingTestInstance : public vkt::TestInstance
1397 {
1398 public:
PipelineLayoutBindingTestInstance(Context & context,const BindingTestConfig & config)1399 	PipelineLayoutBindingTestInstance	(Context& context,
1400 										 const BindingTestConfig& config)
1401 		: vkt::TestInstance				(context)
1402 		, m_renderSize					(2, 2)
1403 		, m_extent						(makeExtent3D(m_renderSize.x(), m_renderSize.y(), 1u))
1404 		, m_format						(VK_FORMAT_R8G8B8A8_UNORM)
1405 		, m_graphicsPipeline			(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(), context.getDevice(), context.getDeviceExtensions(), config.construction)
1406 		, m_config						(config)
1407 	{
1408 	}
~PipelineLayoutBindingTestInstance(void)1409 	~PipelineLayoutBindingTestInstance	(void) {}
1410 	tcu::TestStatus		iterate				(void) override;
1411 
1412 private:
1413 	const tcu::UVec2            m_renderSize;
1414 	const VkExtent3D		    m_extent;
1415 	const VkFormat		        m_format;
1416 	GraphicsPipelineWrapper		m_graphicsPipeline;
1417 	const BindingTestConfig		m_config;
1418 };
1419 
createInstance(Context & context) const1420 TestInstance* PipelineLayoutBindingTestCases::createInstance (Context& context) const
1421 {
1422 	return new PipelineLayoutBindingTestInstance(context, m_config);
1423 }
1424 
checkSupport(Context & context) const1425 void PipelineLayoutBindingTestCases::checkSupport (Context &context) const
1426 {
1427 	checkPipelineConstructionRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_config.construction);
1428 }
1429 
initPrograms(SourceCollections & sources) const1430 void PipelineLayoutBindingTestCases::initPrograms(SourceCollections& sources) const
1431 {
1432 	std::ostringstream src;
1433 	src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1434 		<< "vec2 positions[3] = vec2[](\n"
1435 		<< "		vec2(-1.0, -1.0),"
1436 		<< "		vec2(3.0, -1.0),"
1437 		<< "		vec2(-1.0, 3.0)"
1438 		<< ");\n"
1439 		<< "void main() {\n"
1440 		<< "		gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);\n"
1441 		<< "}";
1442 	sources.glslSources.add("vert") << glu::VertexSource(src.str());
1443 
1444 	std::ostringstream frag;
1445 	frag
1446 		<< glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
1447 		<< "layout (location=0) out vec4 outColor;\n"
1448 		<< "layout(set = 0, binding = 0) uniform Output0 {"
1449 		<< "	uint data;"
1450 		<< "} buf0;\n";
1451 		if (!m_config.holes) {
1452 			frag
1453 				<< "layout(set = 1, binding = 0) uniform Output1 {"
1454 				<< "	uint data;"
1455 				<< "} buf1;\n"
1456 				<< "layout(set = 2, binding = 0) uniform Output2 {"
1457 				<< "	uint data;"
1458 				<< "} buf2;\n"
1459 				<< "\n";
1460 		}
1461 	frag
1462 				<< "layout(set = 3, binding = 0) uniform Output3 {"
1463 				<< "	uint data;"
1464 				<< "} buf3;\n"
1465 				<< "void main ()\n"
1466 				<< "{\n"
1467 				<< "    const vec4 red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1468 				<< "    const vec4 green = vec4(0.0, 1.0, 0.0, 1.0);\n";
1469 		if (!m_config.holes) {
1470 			frag
1471 				<< "    outColor = ((buf0.data == 0) && (buf1.data == 1) && (buf2.data == 2) && (buf3.data == 3)) ? green : red;\n";
1472 		} else {
1473 			frag
1474 				<< "    outColor = ((buf0.data == 0) && (buf3.data == 3)) ? green : red;\n";
1475 		}
1476 		frag << "}\n";
1477 	sources.glslSources.add("frag") << glu::FragmentSource(frag.str());
1478 }
1479 
iterate()1480 tcu::TestStatus PipelineLayoutBindingTestInstance::iterate ()
1481 {
1482 	const auto&			vkd					= m_context.getDeviceInterface();
1483 	const auto			device				= m_context.getDevice();
1484 	auto&				alloc				= m_context.getDefaultAllocator();
1485 	const auto			qIndex				= m_context.getUniversalQueueFamilyIndex();
1486 	const auto			queue				= m_context.getUniversalQueue();
1487 	const auto			tcuFormat			= mapVkFormat(m_format);
1488 	const auto			colorUsage			= (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
1489 	const auto			verifBufferUsage	= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
1490 	const tcu::Vec4		clearColor			(0.0f, 0.0f, 0.0f, 1.0f);
1491 
1492 	// Color attachment.
1493 	const VkImageCreateInfo colorBufferInfo =
1494 	{
1495 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,	//	VkStructureType			sType;
1496 		nullptr,								//	const void*				pNext;
1497 		0u,										//	VkImageCreateFlags		flags;
1498 		VK_IMAGE_TYPE_2D,						//	VkImageType				imageType;
1499 		m_format,								//	VkFormat				format;
1500 		m_extent,								//	VkExtent3D				extent;
1501 		1u,										//	uint32_t				mipLevels;
1502 		1u,										//	uint32_t				arrayLayers;
1503 		VK_SAMPLE_COUNT_1_BIT,					//	VkSampleCountFlagBits	samples;
1504 		VK_IMAGE_TILING_OPTIMAL,				//	VkImageTiling			tiling;
1505 		colorUsage,								//	VkImageUsageFlags		usage;
1506 		VK_SHARING_MODE_EXCLUSIVE,				//	VkSharingMode			sharingMode;
1507 		0u,										//	uint32_t				queueFamilyIndexCount;
1508 		nullptr,								//	const uint32_t*			pQueueFamilyIndices;
1509 		VK_IMAGE_LAYOUT_UNDEFINED,				//	VkImageLayout			initialLayout;
1510 	};
1511 	ImageWithMemory		colorBuffer		(vkd, device, alloc, colorBufferInfo, MemoryRequirement::Any);
1512 	const auto			colorSRR		= makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
1513 	const auto			colorSRL		= makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u);
1514 	const auto			colorBufferView	= makeImageView(vkd, device, colorBuffer.get(), VK_IMAGE_VIEW_TYPE_2D, m_format, colorSRR);
1515 
1516 	// Verification buffer.
1517 	const auto			verifBufferSize		= static_cast<VkDeviceSize>(tcu::getPixelSize(tcuFormat)) * m_extent.width * m_extent.height;
1518 	const auto			verifBufferInfo		= makeBufferCreateInfo(verifBufferSize, verifBufferUsage);
1519 	BufferWithMemory	verifBuffer			(vkd, device, alloc, verifBufferInfo, MemoryRequirement::HostVisible);
1520 	auto&				verifBufferAlloc	= verifBuffer.getAllocation();
1521 
1522 	// Render pass and framebuffer.
1523 	RenderPassWrapper	renderPass			(m_config.construction, vkd, device, m_format);
1524 	renderPass.createFramebuffer(vkd, device, colorBuffer.get(), colorBufferView.get(), m_extent.width, m_extent.height);
1525 
1526 	// Shader modules.
1527 	const auto&		binaries		= m_context.getBinaryCollection();
1528 	const auto		vertModule		= ShaderWrapper(vkd, device, binaries.get("vert"));
1529 	const auto		fragModule		= ShaderWrapper(vkd, device, binaries.get("frag"));
1530 
1531 	// Viewports and scissors.
1532 	const std::vector<VkViewport>	viewports	(1u, makeViewport(m_extent));
1533 	const std::vector<VkRect2D>		scissors	(1u, makeRect2D(m_extent));
1534 
1535 	const VkPipelineVertexInputStateCreateInfo		vertexInputState	= initVulkanStructure();
1536 	const VkPipelineRasterizationStateCreateInfo    rasterizationState  =
1537 	{
1538 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
1539 		DE_NULL,														// const void*                              pNext;
1540 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
1541 		VK_FALSE,														// VkBool32                                 depthClampEnable;
1542 		VK_FALSE,														// VkBool32                                 rasterizerDiscardEnable;
1543 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
1544 		VK_CULL_MODE_NONE,												// VkCullModeFlags							cullMode;
1545 		VK_FRONT_FACE_CLOCKWISE,										// VkFrontFace								frontFace;
1546 		VK_FALSE,														// VkBool32									depthBiasEnable;
1547 		0.0f,															// float									depthBiasConstantFactor;
1548 		0.0f,															// float									depthBiasClamp;
1549 		0.0f,															// float									depthBiasSlopeFactor;
1550 		1.0f,															// float									lineWidth;
1551 	};
1552 
1553 	std::array<int, 4> tmpIndices = {};
1554 	std::array<int, 4> indices = {};
1555 	std::iota(tmpIndices.begin(), tmpIndices.end(), 0);
1556 	if (m_config.backwardsBinding) {
1557 		std::copy(tmpIndices.rbegin(), tmpIndices.rend(), indices.begin());
1558 	} else {
1559 		std::copy(tmpIndices.begin(), tmpIndices.end(), indices.begin());
1560 	}
1561 
1562 	vk::DescriptorSetLayoutBuilder layoutBuilder;
1563 	layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
1564 
1565 	std::vector<vk::Move<VkDescriptorSetLayout>>  descriptorSetLayouts = {};
1566 
1567 	for (size_t i = 0; i < indices.size(); i++) {
1568 		descriptorSetLayouts.emplace_back(layoutBuilder.build(vkd, device));
1569 	}
1570 
1571 	// Pipeline layout and graphics pipeline.
1572 	uint32_t setAndDescriptorCount = de::sizeU32(indices);
1573 	const vk::PipelineLayoutWrapper pipelineLayout	(m_config.construction, vkd, device, descriptorSetLayouts);
1574 	DescriptorPoolBuilder poolBuilder;
1575 	poolBuilder.addType(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, setAndDescriptorCount);
1576 	const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, setAndDescriptorCount);
1577 	std::vector<vk::Move<VkDescriptorSet>> descriptorSetsWrap = {};
1578 	std::vector<VkDescriptorSet> descriptorSets = {};
1579 
1580 	for (const auto& setLayout : descriptorSetLayouts) {
1581 		descriptorSetsWrap.emplace_back(makeDescriptorSet(vkd, device, descriptorPool.get(), setLayout.get()));
1582 	}
1583 
1584 	for (size_t i = 0; i < indices.size(); i++) {
1585 		descriptorSets.emplace_back(descriptorSetsWrap[i].get());
1586 	}
1587 
1588 	const auto			bufferSize		= static_cast<VkDeviceSize>(sizeof(uint32_t));
1589 	std::vector<std::unique_ptr<BufferWithMemory>> buffers;
1590 	//create uniform buffers
1591 	for (size_t i = 0; i < indices.size(); i++) {
1592 		auto outBufferInfo = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
1593 		auto buffer = std::unique_ptr<vk::BufferWithMemory>(new vk::BufferWithMemory(vkd, device, alloc, outBufferInfo, vk::MemoryRequirement::HostVisible));
1594 		auto&				bufferAlloc		= buffer->getAllocation();
1595 		uint32_t*			bufferData		= (uint32_t*)bufferAlloc.getHostPtr();
1596 		*bufferData = (uint32_t)i;
1597 		flushAlloc(vkd, device, bufferAlloc);
1598 		buffers.push_back(std::move(buffer));
1599 	}
1600 
1601 	DescriptorSetUpdateBuilder updater;
1602 
1603 	for (auto i : indices) {
1604 		const auto bufferInfo = makeDescriptorBufferInfo(buffers[i]->get(), 0ull, bufferSize);
1605 		updater.writeSingle(descriptorSets[i], DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, &bufferInfo);
1606 		updater.update(vkd, device);
1607 	}
1608 
1609 	const auto topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1610 	m_graphicsPipeline.setDefaultRasterizationState()
1611 		.setDefaultTopology(topology)
1612 		.setupVertexInputState(&vertexInputState)
1613 		.setDefaultDepthStencilState()
1614 		.setDefaultMultisampleState()
1615 		.setDefaultColorBlendState()
1616 		.setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *renderPass, 0u, vertModule, &rasterizationState)
1617 		.setupFragmentShaderState(pipelineLayout, *renderPass, 0u, fragModule)
1618 		.setupFragmentOutputState(*renderPass)
1619 		.setMonolithicPipelineLayout(pipelineLayout)
1620 		.buildPipeline();
1621 
1622 	// Command pool and buffer.
1623 	const auto cmdPool		= makeCommandPool(vkd, device, qIndex);
1624 	const auto cmdBufferPtr	= allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1625 	const auto cmdBuffer	= cmdBufferPtr.get();
1626 
1627 	beginCommandBuffer(vkd, cmdBuffer);
1628 
1629 	// Draw.
1630 	renderPass.begin(vkd, cmdBuffer, scissors.at(0u), clearColor);
1631 	for (auto i : indices) {
1632 		if (m_config.holes && ((i == 1) || (i == 2))) {
1633 			continue;
1634 		}
1635 		vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), i, 1, &descriptorSets[i], 0u, nullptr);
1636 	}
1637 	m_graphicsPipeline.bind(cmdBuffer);
1638 	vkd.cmdDraw(cmdBuffer, 3, 1u, 0u, 0u);
1639 	renderPass.end(vkd, cmdBuffer);
1640 
1641 	// Copy to verification buffer.
1642 	const auto copyRegion		= makeBufferImageCopy(m_extent, colorSRL);
1643 	const auto transfer2Host	= makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
1644 	const auto color2Transfer	= makeImageMemoryBarrier(
1645 		VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1646 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1647 		colorBuffer.get(), colorSRR);
1648 
1649 	cmdPipelineImageMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, &color2Transfer);
1650 	vkd.cmdCopyImageToBuffer(cmdBuffer, colorBuffer.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, verifBuffer.get(), 1u, &copyRegion);
1651 	cmdPipelineMemoryBarrier(vkd, cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, &transfer2Host);
1652 
1653 	endCommandBuffer(vkd, cmdBuffer);
1654 
1655 	// Submit and validate result.
1656 	submitCommandsAndWait(vkd, device, queue, cmdBuffer);
1657 
1658 	const tcu::IVec3					iExtent (static_cast<int>(m_extent.width), static_cast<int>(m_extent.height), static_cast<int>(m_extent.depth));
1659 	void*								verifBufferData		= verifBufferAlloc.getHostPtr();
1660 	const tcu::ConstPixelBufferAccess	verifAccess		(tcuFormat, iExtent, verifBufferData);
1661 	invalidateAlloc(vkd, device, verifBufferAlloc);
1662 
1663 	const auto green = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
1664 	tcu::TextureLevel referenceLevel(mapVkFormat(m_format), m_extent.height, m_extent.height);
1665 	tcu::PixelBufferAccess reference = referenceLevel.getAccess();
1666 	tcu::clear(reference, green);
1667 
1668 	if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference, verifAccess, tcu::Vec4(0.0), tcu::COMPARE_LOG_ON_ERROR))
1669 		return tcu::TestStatus::fail("Image comparison failed");
1670 
1671 	return tcu::TestStatus::pass("Pass");
1672 }
1673 
1674 } // anonymous
1675 
createMiscTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType)1676 tcu::TestCaseGroup* createMiscTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType)
1677 {
1678 	de::MovePtr<tcu::TestCaseGroup> miscTests (new tcu::TestCaseGroup(testCtx, "misc"));
1679 
1680 	// Location of the Amber script files under the data/vulkan/amber source tree.
1681 	if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1682 		addMonolithicAmberTests(miscTests.get());
1683 
1684 	// Verify implicit access to gl_PrimtiveID works
1685 	miscTests->addChild(new ImplicitPrimitiveIDPassthroughCase(testCtx, "implicit_primitive_id", pipelineConstructionType, false));
1686 	// Verify implicit access to gl_PrimtiveID works with a tessellation shader
1687 	miscTests->addChild(new ImplicitPrimitiveIDPassthroughCase(testCtx, "implicit_primitive_id_with_tessellation", pipelineConstructionType, true));
1688 	#ifndef CTS_USES_VULKANSC
1689 	if (pipelineConstructionType == vk::PIPELINE_CONSTRUCTION_TYPE_FAST_LINKED_LIBRARY) {
1690 		// Check if interpolateAtSample works as expected when using a pipeline library and null MSAA state in the fragment shader"
1691 		miscTests->addChild(new PipelineLibraryInterpolateAtSampleTestCase(testCtx, "interpolate_at_sample_no_sample_shading"));
1692 	}
1693 	#endif
1694 
1695 #ifndef CTS_USES_VULKANSC
1696 	if (isConstructionTypeLibrary(pipelineConstructionType))
1697 	{
1698 		for (int useTessIdx = 0; useTessIdx < 2; ++useTessIdx)
1699 			for (int useGeomIdx = 0; useGeomIdx < 2; ++useGeomIdx)
1700 			{
1701 				const bool useTess = (useTessIdx > 0);
1702 				const bool useGeom = (useGeomIdx > 0);
1703 
1704 				std::string testName = "unused_shader_stages";
1705 
1706 				if (useTess)
1707 					testName += "_include_tess";
1708 
1709 				if (useGeom)
1710 					testName += "_include_geom";
1711 
1712 				const UnusedShaderStageParams params { pipelineConstructionType, useTess, useGeom };
1713 				miscTests->addChild(new UnusedShaderStagesCase(testCtx, testName, params));
1714 			}
1715 	}
1716 #endif // CTS_USES_VULKANSC
1717 
1718 	BindingTestConfig config0 = {pipelineConstructionType, true, false};
1719 	BindingTestConfig config1 = {pipelineConstructionType, false, true};
1720 	BindingTestConfig config2 = {pipelineConstructionType, true, true};
1721 
1722 	// Verify implicit access to gl_PrimtiveID works with a tessellation shader
1723 	miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_backwards", config0));
1724 	// Verify implicit access to gl_PrimtiveID works with a tessellation shader
1725 	miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_holes", config1));
1726 	// Verify implicit access to gl_PrimtiveID works with a tessellation shader
1727 	miscTests->addChild(new PipelineLayoutBindingTestCases(testCtx, "descriptor_bind_test_backwards_holes", config2));
1728 
1729 	return miscTests.release();
1730 }
1731 
1732 } // pipeline
1733 } // vkt
1734