1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Simple Smoke Tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktApiTests.hpp"
25 
26 #include "vktTestCaseUtil.hpp"
27 
28 #include "vkDefs.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkDeviceUtil.hpp"
36 #include "vkPrograms.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkImageUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkObjUtil.hpp"
41 
42 #include "tcuTestLog.hpp"
43 #include "tcuFormatUtil.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuImageCompare.hpp"
46 
47 #include "rrRenderer.hpp"
48 
49 #include "deUniquePtr.hpp"
50 
51 namespace vkt
52 {
53 namespace api
54 {
55 
56 namespace
57 {
58 
59 using namespace vk;
60 using std::vector;
61 using tcu::TestLog;
62 using de::UniquePtr;
63 
createSamplerTest(Context & context)64 tcu::TestStatus createSamplerTest (Context& context)
65 {
66 	const VkDevice			vkDevice	= context.getDevice();
67 	const DeviceInterface&	vk			= context.getDeviceInterface();
68 
69 	{
70 		const struct VkSamplerCreateInfo		samplerInfo	=
71 		{
72 			VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,		// sType
73 			DE_NULL,									// pNext
74 			0u,											// flags
75 			VK_FILTER_NEAREST,							// magFilter
76 			VK_FILTER_NEAREST,							// minFilter
77 			VK_SAMPLER_MIPMAP_MODE_NEAREST,				// mipmapMode
78 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeU
79 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeV
80 			VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,		// addressModeW
81 			0.0f,										// mipLodBias
82 			VK_FALSE,									// anisotropyEnable
83 			1.0f,										// maxAnisotropy
84 			DE_FALSE,									// compareEnable
85 			VK_COMPARE_OP_ALWAYS,						// compareOp
86 			0.0f,										// minLod
87 			0.0f,										// maxLod
88 			VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,	// borderColor
89 			VK_FALSE,									// unnormalizedCoords
90 		};
91 
92 		Move<VkSampler>			tmpSampler	= createSampler(vk, vkDevice, &samplerInfo);
93 		Move<VkSampler>			tmp2Sampler;
94 
95 		tmp2Sampler = tmpSampler;
96 
97 		const Unique<VkSampler>	sampler		(tmp2Sampler);
98 	}
99 
100 	return tcu::TestStatus::pass("Creating sampler succeeded");
101 }
102 
createShaderProgs(SourceCollections & dst)103 void createShaderProgs (SourceCollections& dst)
104 {
105 	dst.glslSources.add("test") << glu::VertexSource(
106 		"#version 310 es\n"
107 		"layout(location = 0) in highp vec4 a_position;\n"
108 		"void main (void) { gl_Position = a_position; }\n");
109 }
110 
createShaderModuleTest(Context & context)111 tcu::TestStatus createShaderModuleTest (Context& context)
112 {
113 	const VkDevice					vkDevice	= context.getDevice();
114 	const DeviceInterface&			vk			= context.getDeviceInterface();
115 	const Unique<VkShaderModule>	shader		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("test"), 0));
116 
117 	return tcu::TestStatus::pass("Creating shader module succeeded");
118 }
119 
createTriangleAsmProgs(SourceCollections & dst)120 void createTriangleAsmProgs (SourceCollections& dst)
121 {
122 	dst.spirvAsmSources.add("vert") <<
123 		"		 OpCapability Shader\n"
124 		"%1 =	 OpExtInstImport \"GLSL.std.450\"\n"
125 		"		 OpMemoryModel Logical GLSL450\n"
126 		"		 OpEntryPoint Vertex %4 \"main\" %10 %12 %16 %17\n"
127 		"		 OpSource ESSL 300\n"
128 		"		 OpName %4 \"main\"\n"
129 		"		 OpName %10 \"gl_Position\"\n"
130 		"		 OpName %12 \"a_position\"\n"
131 		"		 OpName %16 \"gl_VertexIndex\"\n"
132 		"		 OpName %17 \"gl_InstanceIndex\"\n"
133 		"		 OpDecorate %10 BuiltIn Position\n"
134 		"		 OpDecorate %12 Location 0\n"
135 		"		 OpDecorate %16 BuiltIn VertexIndex\n"
136 		"		 OpDecorate %17 BuiltIn InstanceIndex\n"
137 		"%2 =	 OpTypeVoid\n"
138 		"%3 =	 OpTypeFunction %2\n"
139 		"%7 =	 OpTypeFloat 32\n"
140 		"%8 =	 OpTypeVector %7 4\n"
141 		"%9 =	 OpTypePointer Output %8\n"
142 		"%10 =	 OpVariable %9 Output\n"
143 		"%11 =	 OpTypePointer Input %8\n"
144 		"%12 =	 OpVariable %11 Input\n"
145 		"%14 =	 OpTypeInt 32 1\n"
146 		"%15 =	 OpTypePointer Input %14\n"
147 		"%16 =	 OpVariable %15 Input\n"
148 		"%17 =	 OpVariable %15 Input\n"
149 		"%4 =	 OpFunction %2 None %3\n"
150 		"%5 =	 OpLabel\n"
151 		"%13 =	 OpLoad %8 %12\n"
152 		"		 OpStore %10 %13\n"
153 		"		 OpBranch %6\n"
154 		"%6 =	 OpLabel\n"
155 		"		 OpReturn\n"
156 		"		 OpFunctionEnd\n";
157 	dst.spirvAsmSources.add("frag") <<
158 		"		OpCapability Shader\n"
159 		"%1 =	OpExtInstImport \"GLSL.std.450\"\n"
160 		"		OpMemoryModel Logical GLSL450\n"
161 		"		OpEntryPoint Fragment %4 \"main\" %10\n"
162 		"		OpExecutionMode %4 OriginUpperLeft\n"
163 		"		OpSource ESSL 300\n"
164 		"		OpName %4 \"main\"\n"
165 		"		OpName %10 \"o_color\"\n"
166 		"		OpDecorate %10 RelaxedPrecision\n"
167 		"		OpDecorate %10 Location 0\n"
168 		"%2 =	OpTypeVoid\n"
169 		"%3 =	OpTypeFunction %2\n"
170 		"%7 =	OpTypeFloat 32\n"
171 		"%8 =	OpTypeVector %7 4\n"
172 		"%9 =	OpTypePointer Output %8\n"
173 		"%10 =	OpVariable %9 Output\n"
174 		"%11 =	OpConstant %7 1065353216\n"
175 		"%12 =	OpConstant %7 0\n"
176 		"%13 =	OpConstantComposite %8 %11 %12 %11 %11\n"
177 		"%4 =	OpFunction %2 None %3\n"
178 		"%5 =	OpLabel\n"
179 		"		OpStore %10 %13\n"
180 		"		OpBranch %6\n"
181 		"%6 =	OpLabel\n"
182 		"		OpReturn\n"
183 		"		OpFunctionEnd\n";
184 }
185 
createTriangleProgs(SourceCollections & dst)186 void createTriangleProgs (SourceCollections& dst)
187 {
188 	dst.glslSources.add("vert") << glu::VertexSource(
189 		"#version 310 es\n"
190 		"layout(location = 0) in highp vec4 a_position;\n"
191 		"void main (void) { gl_Position = a_position; }\n");
192 	dst.glslSources.add("frag") << glu::FragmentSource(
193 		"#version 310 es\n"
194 		"layout(location = 0) out lowp vec4 o_color;\n"
195 		"void main (void) { o_color = vec4(1.0, 0.0, 1.0, 1.0); }\n");
196 }
197 
createProgsNoOpName(SourceCollections & dst)198 void createProgsNoOpName (SourceCollections& dst)
199 {
200 	dst.spirvAsmSources.add("vert") <<
201 		"OpCapability Shader\n"
202 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
203 		"OpMemoryModel Logical GLSL450\n"
204 		"OpEntryPoint Vertex %4 \"main\" %20 %22 %26\n"
205 		"OpSource ESSL 310\n"
206 		"OpMemberDecorate %18 0 BuiltIn Position\n"
207 		"OpMemberDecorate %18 1 BuiltIn PointSize\n"
208 		"OpDecorate %18 Block\n"
209 		"OpDecorate %22 Location 0\n"
210 		"OpDecorate %26 Location 2\n"
211 		"%2 = OpTypeVoid\n"
212 		"%3 = OpTypeFunction %2\n"
213 		"%6 = OpTypeFloat 32\n"
214 		"%7 = OpTypeVector %6 4\n"
215 		"%8 = OpTypeStruct %7\n"
216 		"%9 = OpTypePointer Function %8\n"
217 		"%11 = OpTypeInt 32 1\n"
218 		"%12 = OpConstant %11 0\n"
219 		"%13 = OpConstant %6 1\n"
220 		"%14 = OpConstant %6 0\n"
221 		"%15 = OpConstantComposite %7 %13 %14 %13 %13\n"
222 		"%16 = OpTypePointer Function %7\n"
223 		"%18 = OpTypeStruct %7 %6\n"
224 		"%19 = OpTypePointer Output %18\n"
225 		"%20 = OpVariable %19 Output\n"
226 		"%21 = OpTypePointer Input %7\n"
227 		"%22 = OpVariable %21 Input\n"
228 		"%24 = OpTypePointer Output %7\n"
229 		"%26 = OpVariable %24 Output\n"
230 		"%4 = OpFunction %2 None %3\n"
231 		"%5 = OpLabel\n"
232 		"%10 = OpVariable %9 Function\n"
233 		"%17 = OpAccessChain %16 %10 %12\n"
234 		"OpStore %17 %15\n"
235 		"%23 = OpLoad %7 %22\n"
236 		"%25 = OpAccessChain %24 %20 %12\n"
237 		"OpStore %25 %23\n"
238 		"%27 = OpAccessChain %16 %10 %12\n"
239 		"%28 = OpLoad %7 %27\n"
240 		"OpStore %26 %28\n"
241 		"OpReturn\n"
242 		"OpFunctionEnd\n";
243 	dst.spirvAsmSources.add("frag") <<
244 		"OpCapability Shader\n"
245 		"%1 = OpExtInstImport \"GLSL.std.450\"\n"
246 		"OpMemoryModel Logical GLSL450\n"
247 		"OpEntryPoint Fragment %4 \"main\" %9 %11\n"
248 		"OpExecutionMode %4 OriginUpperLeft\n"
249 		"OpSource ESSL 310\n"
250 		"OpDecorate %9 RelaxedPrecision\n"
251 		"OpDecorate %9 Location 0\n"
252 		"OpDecorate %11 Location 2\n"
253 		"%2 = OpTypeVoid\n"
254 		"%3 = OpTypeFunction %2\n"
255 		"%6 = OpTypeFloat 32\n"
256 		"%7 = OpTypeVector %6 4\n"
257 		"%8 = OpTypePointer Output %7\n"
258 		"%9 = OpVariable %8 Output\n"
259 		"%10 = OpTypePointer Input %7\n"
260 		"%11 = OpVariable %10 Input\n"
261 		"%4 = OpFunction %2 None %3\n"
262 		"%5 = OpLabel\n"
263 		"%12 = OpLoad %7 %11\n"
264 		"OpStore %9 %12\n"
265 		"OpReturn\n"
266 		"OpFunctionEnd\n";
267 }
268 
269 class RefVertexShader : public rr::VertexShader
270 {
271 public:
RefVertexShader(void)272 	RefVertexShader (void)
273 		: rr::VertexShader(1, 0)
274 	{
275 		m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
276 	}
277 
shadeVertices(const rr::VertexAttrib * inputs,rr::VertexPacket * const * packets,const int numPackets) const278 	void shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
279 	{
280 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
281 		{
282 			packets[packetNdx]->position = rr::readVertexAttribFloat(inputs[0],
283 																	 packets[packetNdx]->instanceNdx,
284 																	 packets[packetNdx]->vertexNdx);
285 		}
286 	}
287 };
288 
289 class RefFragmentShader : public rr::FragmentShader
290 {
291 public:
RefFragmentShader(void)292 	RefFragmentShader (void)
293 		: rr::FragmentShader(0, 1)
294 	{
295 		m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
296 	}
297 
shadeFragments(rr::FragmentPacket *,const int numPackets,const rr::FragmentShadingContext & context) const298 	void shadeFragments (rr::FragmentPacket*, const int numPackets, const rr::FragmentShadingContext& context) const
299 	{
300 		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
301 		{
302 			for (int fragNdx = 0; fragNdx < rr::NUM_FRAGMENTS_PER_PACKET; ++fragNdx)
303 			{
304 				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(1.0f, 0.0f, 1.0f, 1.0f));
305 			}
306 		}
307 	}
308 };
309 
renderReferenceTriangle(const tcu::PixelBufferAccess & dst,const tcu::Vec4 (& vertices)[3])310 void renderReferenceTriangle (const tcu::PixelBufferAccess& dst, const tcu::Vec4 (&vertices)[3])
311 {
312 	const RefVertexShader					vertShader;
313 	const RefFragmentShader					fragShader;
314 	const rr::Program						program			(&vertShader, &fragShader);
315 	const rr::MultisamplePixelBufferAccess	colorBuffer		= rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(dst);
316 	const rr::RenderTarget					renderTarget	(colorBuffer);
317 	const rr::RenderState					renderState		((rr::ViewportState(colorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT);
318 	const rr::Renderer						renderer;
319 	const rr::VertexAttrib					vertexAttribs[]	=
320 	{
321 		rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, vertices[0].getPtr())
322 	};
323 
324 	renderer.draw(rr::DrawCommand(renderState,
325 								  renderTarget,
326 								  program,
327 								  DE_LENGTH_OF_ARRAY(vertexAttribs),
328 								  &vertexAttribs[0],
329 								  rr::PrimitiveList(rr::PRIMITIVETYPE_TRIANGLES, DE_LENGTH_OF_ARRAY(vertices), 0)));
330 }
331 
renderTriangleTest(Context & context)332 tcu::TestStatus renderTriangleTest (Context& context)
333 {
334 	const VkDevice							vkDevice				= context.getDevice();
335 	const DeviceInterface&					vk						= context.getDeviceInterface();
336 	const VkQueue							queue					= context.getUniversalQueue();
337 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
338 	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
339 	const tcu::IVec2						renderSize				(256, 256);
340 	const VkFormat							colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
341 	const tcu::Vec4							clearColor				(0.125f, 0.25f, 0.75f, 1.0f);
342 
343 	const tcu::Vec4							vertices[]				=
344 	{
345 		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
346 		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
347 		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
348 	};
349 
350 	const VkBufferCreateInfo				vertexBufferParams		=
351 	{
352 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
353 		DE_NULL,								// pNext
354 		0u,										// flags
355 		(VkDeviceSize)sizeof(vertices),			// size
356 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// usage
357 		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
358 		1u,										// queueFamilyIndexCount
359 		&queueFamilyIndex,						// pQueueFamilyIndices
360 	};
361 	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, vkDevice, &vertexBufferParams));
362 	const UniquePtr<Allocation>				vertexBufferMemory		(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
363 
364 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
365 
366 	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
367 	const VkBufferCreateInfo				readImageBufferParams	=
368 	{
369 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
370 		DE_NULL,									// pNext
371 		(VkBufferCreateFlags)0u,					// flags
372 		imageSizeBytes,								// size
373 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
374 		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
375 		1u,											// queueFamilyIndexCount
376 		&queueFamilyIndex,							// pQueueFamilyIndices
377 	};
378 	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, vkDevice, &readImageBufferParams));
379 	const UniquePtr<Allocation>				readImageBufferMemory	(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
380 
381 	VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
382 
383 	const VkImageCreateInfo					imageParams				=
384 	{
385 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// sType
386 		DE_NULL,																// pNext
387 		0u,																		// flags
388 		VK_IMAGE_TYPE_2D,														// imageType
389 		VK_FORMAT_R8G8B8A8_UNORM,												// format
390 		{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },				// extent
391 		1u,																		// mipLevels
392 		1u,																		// arraySize
393 		VK_SAMPLE_COUNT_1_BIT,													// samples
394 		VK_IMAGE_TILING_OPTIMAL,												// tiling
395 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// usage
396 		VK_SHARING_MODE_EXCLUSIVE,												// sharingMode
397 		1u,																		// queueFamilyIndexCount
398 		&queueFamilyIndex,														// pQueueFamilyIndices
399 		VK_IMAGE_LAYOUT_UNDEFINED,												// initialLayout
400 	};
401 
402 	const Unique<VkImage>					image					(createImage(vk, vkDevice, &imageParams));
403 	const UniquePtr<Allocation>				imageMemory				(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
404 
405 	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
406 
407 	const Unique<VkRenderPass>				renderPass				(makeRenderPass(vk, vkDevice, VK_FORMAT_R8G8B8A8_UNORM));
408 
409 	const VkImageViewCreateInfo				colorAttViewParams		=
410 	{
411 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
412 		DE_NULL,										// pNext
413 		0u,												// flags
414 		*image,											// image
415 		VK_IMAGE_VIEW_TYPE_2D,							// viewType
416 		VK_FORMAT_R8G8B8A8_UNORM,						// format
417 		{
418 			VK_COMPONENT_SWIZZLE_R,
419 			VK_COMPONENT_SWIZZLE_G,
420 			VK_COMPONENT_SWIZZLE_B,
421 			VK_COMPONENT_SWIZZLE_A
422 		},												// components
423 		{
424 			VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
425 			0u,												// baseMipLevel
426 			1u,												// levelCount
427 			0u,												// baseArrayLayer
428 			1u,												// layerCount
429 		},												// subresourceRange
430 	};
431 	const Unique<VkImageView>				colorAttView			(createImageView(vk, vkDevice, &colorAttViewParams));
432 
433 	// Pipeline layout
434 	const VkPipelineLayoutCreateInfo		pipelineLayoutParams	=
435 	{
436 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType
437 		DE_NULL,												// pNext
438 		(vk::VkPipelineLayoutCreateFlags)0,
439 		0u,														// setLayoutCount
440 		DE_NULL,												// pSetLayouts
441 		0u,														// pushConstantRangeCount
442 		DE_NULL,												// pPushConstantRanges
443 	};
444 	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
445 
446 	// Shaders
447 	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
448 	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
449 
450 	// Pipeline
451 	const std::vector<VkViewport>			viewports				(1, makeViewport(renderSize));
452 	const std::vector<VkRect2D>				scissors				(1, makeRect2D(renderSize));
453 
454 	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk,					// const DeviceInterface&            vk
455 																						  vkDevice,				// const VkDevice                    device
456 																						  *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
457 																						  *vertShaderModule,	// const VkShaderModule              vertexShaderModule
458 																						  DE_NULL,				// const VkShaderModule              tessellationControlModule
459 																						  DE_NULL,				// const VkShaderModule              tessellationEvalModule
460 																						  DE_NULL,				// const VkShaderModule              geometryShaderModule
461 																						  *fragShaderModule,	// const VkShaderModule              fragmentShaderModule
462 																						  *renderPass,			// const VkRenderPass                renderPass
463 																						  viewports,			// const std::vector<VkViewport>&    viewports
464 																						  scissors));			// const std::vector<VkRect2D>&      scissors
465 
466 	// Framebuffer
467 	const VkFramebufferCreateInfo			framebufferParams		=
468 	{
469 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// sType
470 		DE_NULL,												// pNext
471 		0u,														// flags
472 		*renderPass,											// renderPass
473 		1u,														// attachmentCount
474 		&*colorAttView,											// pAttachments
475 		(deUint32)renderSize.x(),								// width
476 		(deUint32)renderSize.y(),								// height
477 		1u,														// layers
478 	};
479 	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, vkDevice, &framebufferParams));
480 
481 	const VkCommandPoolCreateInfo			cmdPoolParams			=
482 	{
483 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType
484 		DE_NULL,													// pNext
485 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags
486 		queueFamilyIndex,											// queueFamilyIndex
487 	};
488 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
489 
490 	// Command buffer
491 	const VkCommandBufferAllocateInfo		cmdBufParams			=
492 	{
493 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// sType
494 		DE_NULL,												// pNext
495 		*cmdPool,												// pool
496 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// level
497 		1u,														// bufferCount
498 	};
499 	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
500 
501 	// Record commands
502 	beginCommandBuffer(vk, *cmdBuf);
503 
504 	{
505 		const VkMemoryBarrier		vertFlushBarrier	=
506 		{
507 			VK_STRUCTURE_TYPE_MEMORY_BARRIER,			// sType
508 			DE_NULL,									// pNext
509 			VK_ACCESS_HOST_WRITE_BIT,					// srcAccessMask
510 			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		// dstAccessMask
511 		};
512 		const VkImageMemoryBarrier	colorAttBarrier		=
513 		{
514 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType
515 			DE_NULL,									// pNext
516 			0u,											// srcAccessMask
517 			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
518 			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),		// dstAccessMask
519 			VK_IMAGE_LAYOUT_UNDEFINED,					// oldLayout
520 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// newLayout
521 			queueFamilyIndex,							// srcQueueFamilyIndex
522 			queueFamilyIndex,							// dstQueueFamilyIndex
523 			*image,										// image
524 			{
525 				VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
526 				0u,											// baseMipLevel
527 				1u,											// levelCount
528 				0u,											// baseArrayLayer
529 				1u,											// layerCount
530 			}											// subresourceRange
531 		};
532 		vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier);
533 	}
534 
535 	beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), clearColor);
536 
537 	vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
538 	{
539 		const VkDeviceSize bindingOffset = 0;
540 		vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
541 	}
542 	vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
543 	endRenderPass(vk, *cmdBuf);
544 	copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
545 	endCommandBuffer(vk, *cmdBuf);
546 
547 	// Upload vertex data
548 	deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
549 	flushAlloc(vk, vkDevice, *vertexBufferMemory);
550 
551 	// Submit & wait for completion
552 	submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
553 
554 	// Read results, render reference, compare
555 	{
556 		const tcu::TextureFormat			tcuFormat		= vk::mapVkFormat(colorFormat);
557 		const VkMappedMemoryRange			range			=
558 		{
559 			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType
560 			DE_NULL,								// pNext
561 			readImageBufferMemory->getMemory(),		// memory
562 			0,										// offset
563 			imageSizeBytes,							// size
564 		};
565 		const tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
566 
567 		VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
568 
569 		{
570 			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
571 			const tcu::UVec4	threshold		(0u);
572 			const tcu::IVec3	posDeviation	(1,1,0);
573 
574 			tcu::clear(refImage.getAccess(), clearColor);
575 			renderReferenceTriangle(refImage.getAccess(), vertices);
576 
577 			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
578 														  "ComparisonResult",
579 														  "Image comparison result",
580 														  refImage.getAccess(),
581 														  resultAccess,
582 														  threshold,
583 														  posDeviation,
584 														  false,
585 														  tcu::COMPARE_LOG_RESULT))
586 				return tcu::TestStatus::pass("Rendering succeeded");
587 			else
588 				return tcu::TestStatus::fail("Image comparison failed");
589 		}
590 	}
591 
592 	return tcu::TestStatus::pass("Rendering succeeded");
593 }
594 
renderTriangleUnusedResolveAttachmentTest(Context & context)595 tcu::TestStatus renderTriangleUnusedResolveAttachmentTest (Context& context)
596 {
597 	const VkDevice							vkDevice				= context.getDevice();
598 	const DeviceInterface&					vk						= context.getDeviceInterface();
599 	const VkQueue							queue					= context.getUniversalQueue();
600 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
601 	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
602 	const tcu::IVec2						renderSize				(256, 256);
603 	const VkFormat							colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
604 	const tcu::Vec4							clearColor				(0.125f, 0.25f, 0.75f, 1.0f);
605 
606 	const tcu::Vec4							vertices[]				=
607 	{
608 		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
609 		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
610 		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
611 	};
612 
613 	const VkBufferCreateInfo				vertexBufferParams		=
614 	{
615 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
616 		DE_NULL,								// pNext
617 		0u,										// flags
618 		(VkDeviceSize)sizeof(vertices),			// size
619 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// usage
620 		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
621 		1u,										// queueFamilyIndexCount
622 		&queueFamilyIndex,						// pQueueFamilyIndices
623 	};
624 	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, vkDevice, &vertexBufferParams));
625 	const UniquePtr<Allocation>				vertexBufferMemory		(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
626 
627 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
628 
629 	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
630 	const VkBufferCreateInfo				readImageBufferParams	=
631 	{
632 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
633 		DE_NULL,									// pNext
634 		(VkBufferCreateFlags)0u,					// flags
635 		imageSizeBytes,								// size
636 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
637 		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
638 		1u,											// queueFamilyIndexCount
639 		&queueFamilyIndex,							// pQueueFamilyIndices
640 	};
641 	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, vkDevice, &readImageBufferParams));
642 	const UniquePtr<Allocation>				readImageBufferMemory	(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
643 
644 	VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
645 
646 	const VkImageCreateInfo					imageParams				=
647 	{
648 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// sType
649 		DE_NULL,																// pNext
650 		0u,																		// flags
651 		VK_IMAGE_TYPE_2D,														// imageType
652 		VK_FORMAT_R8G8B8A8_UNORM,												// format
653 		{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },				// extent
654 		1u,																		// mipLevels
655 		1u,																		// arraySize
656 		VK_SAMPLE_COUNT_1_BIT,													// samples
657 		VK_IMAGE_TILING_OPTIMAL,												// tiling
658 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// usage
659 		VK_SHARING_MODE_EXCLUSIVE,												// sharingMode
660 		1u,																		// queueFamilyIndexCount
661 		&queueFamilyIndex,														// pQueueFamilyIndices
662 		VK_IMAGE_LAYOUT_UNDEFINED,												// initialLayout
663 	};
664 
665 	const Unique<VkImage>					image					(createImage(vk, vkDevice, &imageParams));
666 	const UniquePtr<Allocation>				imageMemory				(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
667 
668 	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
669 
670 	const VkAttachmentDescription			colorAttDesc			=
671 	{
672 		0u,												// flags
673 		VK_FORMAT_R8G8B8A8_UNORM,						// format
674 		VK_SAMPLE_COUNT_1_BIT,							// samples
675 		VK_ATTACHMENT_LOAD_OP_CLEAR,					// loadOp
676 		VK_ATTACHMENT_STORE_OP_STORE,					// storeOp
677 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// stencilLoadOp
678 		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// stencilStoreOp
679 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// initialLayout
680 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// finalLayout
681 	};
682 	const VkAttachmentReference				colorAttRef				=
683 	{
684 		0u,												// attachment
685 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// layout
686 	};
687 	const VkAttachmentReference				resolveAttRef			=
688 	{
689 		VK_ATTACHMENT_UNUSED,
690 		VK_IMAGE_LAYOUT_GENERAL
691 	};
692 	const VkSubpassDescription				subpassDesc				=
693 	{
694 		(VkSubpassDescriptionFlags)0u,					// flags
695 		VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
696 		0u,												// inputAttachmentCount
697 		DE_NULL,										// pInputAttachments
698 		1u,												// colorAttachmentCount
699 		&colorAttRef,									// pColorAttachments
700 		&resolveAttRef,									// pResolveAttachments
701 		DE_NULL,										// depthStencilAttachment
702 		0u,												// preserveAttachmentCount
703 		DE_NULL,										// pPreserveAttachments
704 	};
705 	const VkRenderPassCreateInfo			renderPassParams		=
706 	{
707 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// sType
708 		DE_NULL,										// pNext
709 		0u,												// flags
710 		1u,												// attachmentCount
711 		&colorAttDesc,									// pAttachments
712 		1u,												// subpassCount
713 		&subpassDesc,									// pSubpasses
714 		0u,												// dependencyCount
715 		DE_NULL,										// pDependencies
716 	};
717 	const Unique<VkRenderPass>				renderPass				(createRenderPass(vk, vkDevice, &renderPassParams));
718 
719 	const VkImageViewCreateInfo				colorAttViewParams		=
720 	{
721 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
722 		DE_NULL,										// pNext
723 		0u,												// flags
724 		*image,											// image
725 		VK_IMAGE_VIEW_TYPE_2D,							// viewType
726 		VK_FORMAT_R8G8B8A8_UNORM,						// format
727 		{
728 			VK_COMPONENT_SWIZZLE_R,
729 			VK_COMPONENT_SWIZZLE_G,
730 			VK_COMPONENT_SWIZZLE_B,
731 			VK_COMPONENT_SWIZZLE_A
732 		},												// components
733 		{
734 			VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
735 			0u,												// baseMipLevel
736 			1u,												// levelCount
737 			0u,												// baseArrayLayer
738 			1u,												// layerCount
739 		},												// subresourceRange
740 	};
741 	const Unique<VkImageView>				colorAttView			(createImageView(vk, vkDevice, &colorAttViewParams));
742 
743 	// Pipeline layout
744 	const VkPipelineLayoutCreateInfo		pipelineLayoutParams	=
745 	{
746 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType
747 		DE_NULL,												// pNext
748 		(vk::VkPipelineLayoutCreateFlags)0,
749 		0u,														// setLayoutCount
750 		DE_NULL,												// pSetLayouts
751 		0u,														// pushConstantRangeCount
752 		DE_NULL,												// pPushConstantRanges
753 	};
754 	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
755 
756 	// Shaders
757 	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
758 	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
759 
760 	// Pipeline
761 	const std::vector<VkViewport>			viewports				(1, makeViewport(renderSize));
762 	const std::vector<VkRect2D>				scissors				(1, makeRect2D(renderSize));
763 
764 	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk,					// const DeviceInterface&            vk
765 																						  vkDevice,				// const VkDevice                    device
766 																						  *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
767 																						  *vertShaderModule,	// const VkShaderModule              vertexShaderModule
768 																						  DE_NULL,				// const VkShaderModule              tessellationControlShaderModule
769 																						  DE_NULL,				// const VkShaderModule              tessellationEvalShaderModule
770 																						  DE_NULL,				// const VkShaderModule              geometryShaderModule
771 																						  *fragShaderModule,	// const VkShaderModule              fragmentShaderModule
772 																						  *renderPass,			// const VkRenderPass                renderPass
773 																						  viewports,			// const std::vector<VkViewport>&    viewports
774 																						  scissors));			// const std::vector<VkRect2D>&      scissors
775 
776 	// Framebuffer
777 	const VkFramebufferCreateInfo			framebufferParams		=
778 	{
779 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// sType
780 		DE_NULL,												// pNext
781 		0u,														// flags
782 		*renderPass,											// renderPass
783 		1u,														// attachmentCount
784 		&*colorAttView,											// pAttachments
785 		(deUint32)renderSize.x(),								// width
786 		(deUint32)renderSize.y(),								// height
787 		1u,														// layers
788 	};
789 	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, vkDevice, &framebufferParams));
790 
791 	const VkCommandPoolCreateInfo			cmdPoolParams			=
792 	{
793 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType
794 		DE_NULL,													// pNext
795 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags
796 		queueFamilyIndex,											// queueFamilyIndex
797 	};
798 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
799 
800 	// Command buffer
801 	const VkCommandBufferAllocateInfo		cmdBufParams			=
802 	{
803 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// sType
804 		DE_NULL,												// pNext
805 		*cmdPool,												// pool
806 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// level
807 		1u,														// bufferCount
808 	};
809 	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
810 
811 	// Record commands
812 	beginCommandBuffer(vk, *cmdBuf);
813 
814 	{
815 		const VkMemoryBarrier		vertFlushBarrier	=
816 		{
817 			VK_STRUCTURE_TYPE_MEMORY_BARRIER,			// sType
818 			DE_NULL,									// pNext
819 			VK_ACCESS_HOST_WRITE_BIT,					// srcAccessMask
820 			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		// dstAccessMask
821 		};
822 		const VkImageMemoryBarrier	colorAttBarrier		=
823 		{
824 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType
825 			DE_NULL,									// pNext
826 			0u,											// srcAccessMask
827 			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
828 			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),		// dstAccessMask
829 			VK_IMAGE_LAYOUT_UNDEFINED,					// oldLayout
830 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// newLayout
831 			queueFamilyIndex,							// srcQueueFamilyIndex
832 			queueFamilyIndex,							// dstQueueFamilyIndex
833 			*image,										// image
834 			{
835 				VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
836 				0u,											// baseMipLevel
837 				1u,											// levelCount
838 				0u,											// baseArrayLayer
839 				1u,											// layerCount
840 			}											// subresourceRange
841 		};
842 		vk.cmdPipelineBarrier(*cmdBuf, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, (VkDependencyFlags)0, 1, &vertFlushBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &colorAttBarrier);
843 	}
844 
845 	beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), clearColor);
846 
847 	vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
848 	{
849 		const VkDeviceSize bindingOffset = 0;
850 		vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
851 	}
852 	vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
853 	endRenderPass(vk, *cmdBuf);
854 	copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
855 	endCommandBuffer(vk, *cmdBuf);
856 
857 	// Upload vertex data
858 	deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
859 	flushAlloc(vk, vkDevice, *vertexBufferMemory);
860 
861 	// Submit & wait for completion
862 	submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
863 
864 	// Read results, render reference, compare
865 	{
866 		const tcu::TextureFormat			tcuFormat		= vk::mapVkFormat(colorFormat);
867 		const VkMappedMemoryRange			range			=
868 		{
869 			VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,	// sType
870 			DE_NULL,								// pNext
871 			readImageBufferMemory->getMemory(),		// memory
872 			0,										// offset
873 			imageSizeBytes,							// size
874 		};
875 		const tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
876 
877 		VK_CHECK(vk.invalidateMappedMemoryRanges(vkDevice, 1u, &range));
878 
879 		{
880 			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
881 			const tcu::UVec4	threshold		(0u);
882 			const tcu::IVec3	posDeviation	(1,1,0);
883 
884 			tcu::clear(refImage.getAccess(), clearColor);
885 			renderReferenceTriangle(refImage.getAccess(), vertices);
886 
887 			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
888 														  "ComparisonResult",
889 														  "Image comparison result",
890 														  refImage.getAccess(),
891 														  resultAccess,
892 														  threshold,
893 														  posDeviation,
894 														  false,
895 														  tcu::COMPARE_LOG_RESULT))
896 				return tcu::TestStatus::pass("Rendering succeeded");
897 			else
898 				return tcu::TestStatus::fail("Image comparison failed");
899 		}
900 	}
901 
902 	return tcu::TestStatus::pass("Rendering succeeded");
903 }
904 
905 } // anonymous
906 
createSmokeTests(tcu::TestContext & testCtx)907 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& testCtx)
908 {
909 	de::MovePtr<tcu::TestCaseGroup>	smokeTests	(new tcu::TestCaseGroup(testCtx, "smoke", "Smoke Tests"));
910 
911 	addFunctionCase				(smokeTests.get(), "create_sampler",			"",	createSamplerTest);
912 	addFunctionCaseWithPrograms	(smokeTests.get(), "create_shader",				"", createShaderProgs,		createShaderModuleTest);
913 	addFunctionCaseWithPrograms	(smokeTests.get(), "triangle",					"", createTriangleProgs,	renderTriangleTest);
914 	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle",				"", createTriangleAsmProgs,	renderTriangleTest);
915 	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle_no_opname",	"", createProgsNoOpName,	renderTriangleTest);
916 	addFunctionCaseWithPrograms	(smokeTests.get(), "unused_resolve_attachment",	"", createTriangleProgs,	renderTriangleUnusedResolveAttachmentTest);
917 
918 	return smokeTests.release();
919 }
920 
921 } // api
922 } // vkt
923