• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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],const int subpixelBits)310 void renderReferenceTriangle (const tcu::PixelBufferAccess& dst, const tcu::Vec4 (&vertices)[3], const int subpixelBits)
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)), subpixelBits, 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 tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
558 
559 		invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
560 
561 		{
562 			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
563 			const tcu::UVec4	threshold		(0u);
564 			const tcu::IVec3	posDeviation	(1,1,0);
565 
566 			tcu::clear(refImage.getAccess(), clearColor);
567 			renderReferenceTriangle(refImage.getAccess(), vertices, context.getDeviceProperties().limits.subPixelPrecisionBits);
568 
569 			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
570 														  "ComparisonResult",
571 														  "Image comparison result",
572 														  refImage.getAccess(),
573 														  resultAccess,
574 														  threshold,
575 														  posDeviation,
576 														  false,
577 														  tcu::COMPARE_LOG_RESULT))
578 				return tcu::TestStatus::pass("Rendering succeeded");
579 			else
580 				return tcu::TestStatus::fail("Image comparison failed");
581 		}
582 	}
583 
584 	return tcu::TestStatus::pass("Rendering succeeded");
585 }
586 
587 struct VoidVulkanStruct
588 {
589 	VkStructureType sType;
590 	const void*		pNext;
591 };
592 
renderTriangleUnusedResolveAttachmentTest(Context & context)593 tcu::TestStatus renderTriangleUnusedResolveAttachmentTest (Context& context)
594 {
595 	const VkDevice							vkDevice				= context.getDevice();
596 	const DeviceInterface&					vk						= context.getDeviceInterface();
597 	const VkQueue							queue					= context.getUniversalQueue();
598 	const deUint32							queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
599 	SimpleAllocator							memAlloc				(vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
600 	const tcu::IVec2						renderSize				(256, 256);
601 	const VkFormat							colorFormat				= VK_FORMAT_R8G8B8A8_UNORM;
602 	const tcu::Vec4							clearColor				(0.125f, 0.25f, 0.75f, 1.0f);
603 
604 	const tcu::Vec4							vertices[]				=
605 	{
606 		tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
607 		tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
608 		tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
609 	};
610 
611 	const VkBufferCreateInfo				vertexBufferParams		=
612 	{
613 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
614 		DE_NULL,								// pNext
615 		0u,										// flags
616 		(VkDeviceSize)sizeof(vertices),			// size
617 		VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,		// usage
618 		VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
619 		1u,										// queueFamilyIndexCount
620 		&queueFamilyIndex,						// pQueueFamilyIndices
621 	};
622 	const Unique<VkBuffer>					vertexBuffer			(createBuffer(vk, vkDevice, &vertexBufferParams));
623 	const UniquePtr<Allocation>				vertexBufferMemory		(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *vertexBuffer), MemoryRequirement::HostVisible));
624 
625 	VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferMemory->getMemory(), vertexBufferMemory->getOffset()));
626 
627 	const VkDeviceSize						imageSizeBytes			= (VkDeviceSize)(sizeof(deUint32)*renderSize.x()*renderSize.y());
628 	const VkBufferCreateInfo				readImageBufferParams	=
629 	{
630 		VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,		// sType
631 		DE_NULL,									// pNext
632 		(VkBufferCreateFlags)0u,					// flags
633 		imageSizeBytes,								// size
634 		VK_BUFFER_USAGE_TRANSFER_DST_BIT,			// usage
635 		VK_SHARING_MODE_EXCLUSIVE,					// sharingMode
636 		1u,											// queueFamilyIndexCount
637 		&queueFamilyIndex,							// pQueueFamilyIndices
638 	};
639 	const Unique<VkBuffer>					readImageBuffer			(createBuffer(vk, vkDevice, &readImageBufferParams));
640 	const UniquePtr<Allocation>				readImageBufferMemory	(memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *readImageBuffer), MemoryRequirement::HostVisible));
641 
642 	VK_CHECK(vk.bindBufferMemory(vkDevice, *readImageBuffer, readImageBufferMemory->getMemory(), readImageBufferMemory->getOffset()));
643 
644 	const VkImageCreateInfo					imageParams				=
645 	{
646 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,									// sType
647 		DE_NULL,																// pNext
648 		0u,																		// flags
649 		VK_IMAGE_TYPE_2D,														// imageType
650 		VK_FORMAT_R8G8B8A8_UNORM,												// format
651 		{ (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1 },				// extent
652 		1u,																		// mipLevels
653 		1u,																		// arraySize
654 		VK_SAMPLE_COUNT_1_BIT,													// samples
655 		VK_IMAGE_TILING_OPTIMAL,												// tiling
656 		VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT,	// usage
657 		VK_SHARING_MODE_EXCLUSIVE,												// sharingMode
658 		1u,																		// queueFamilyIndexCount
659 		&queueFamilyIndex,														// pQueueFamilyIndices
660 		VK_IMAGE_LAYOUT_UNDEFINED,												// initialLayout
661 	};
662 
663 	const Unique<VkImage>					image					(createImage(vk, vkDevice, &imageParams));
664 	const UniquePtr<Allocation>				imageMemory				(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image), MemoryRequirement::Any));
665 
666 	VK_CHECK(vk.bindImageMemory(vkDevice, *image, imageMemory->getMemory(), imageMemory->getOffset()));
667 
668 	const VkAttachmentDescription			colorAttDesc			=
669 	{
670 		0u,												// flags
671 		VK_FORMAT_R8G8B8A8_UNORM,						// format
672 		VK_SAMPLE_COUNT_1_BIT,							// samples
673 		VK_ATTACHMENT_LOAD_OP_CLEAR,					// loadOp
674 		VK_ATTACHMENT_STORE_OP_STORE,					// storeOp
675 		VK_ATTACHMENT_LOAD_OP_DONT_CARE,				// stencilLoadOp
676 		VK_ATTACHMENT_STORE_OP_DONT_CARE,				// stencilStoreOp
677 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// initialLayout
678 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// finalLayout
679 	};
680 	const VkAttachmentReference				colorAttRef				=
681 	{
682 		0u,												// attachment
683 		VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,		// layout
684 	};
685 	const VkAttachmentReference				resolveAttRef			=
686 	{
687 		VK_ATTACHMENT_UNUSED,
688 		VK_IMAGE_LAYOUT_GENERAL
689 	};
690 	const VkSubpassDescription				subpassDesc				=
691 	{
692 		(VkSubpassDescriptionFlags)0u,					// flags
693 		VK_PIPELINE_BIND_POINT_GRAPHICS,				// pipelineBindPoint
694 		0u,												// inputAttachmentCount
695 		DE_NULL,										// pInputAttachments
696 		1u,												// colorAttachmentCount
697 		&colorAttRef,									// pColorAttachments
698 		&resolveAttRef,									// pResolveAttachments
699 		DE_NULL,										// depthStencilAttachment
700 		0u,												// preserveAttachmentCount
701 		DE_NULL,										// pPreserveAttachments
702 	};
703 	const VkRenderPassCreateInfo			renderPassParams		=
704 	{
705 		VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,		// sType
706 		DE_NULL,										// pNext
707 		0u,												// flags
708 		1u,												// attachmentCount
709 		&colorAttDesc,									// pAttachments
710 		1u,												// subpassCount
711 		&subpassDesc,									// pSubpasses
712 		0u,												// dependencyCount
713 		DE_NULL,										// pDependencies
714 	};
715 	const Unique<VkRenderPass>				renderPass				(createRenderPass(vk, vkDevice, &renderPassParams));
716 
717 	const VkImageViewCreateInfo				colorAttViewParams		=
718 	{
719 		VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
720 		DE_NULL,										// pNext
721 		0u,												// flags
722 		*image,											// image
723 		VK_IMAGE_VIEW_TYPE_2D,							// viewType
724 		VK_FORMAT_R8G8B8A8_UNORM,						// format
725 		{
726 			VK_COMPONENT_SWIZZLE_R,
727 			VK_COMPONENT_SWIZZLE_G,
728 			VK_COMPONENT_SWIZZLE_B,
729 			VK_COMPONENT_SWIZZLE_A
730 		},												// components
731 		{
732 			VK_IMAGE_ASPECT_COLOR_BIT,						// aspectMask
733 			0u,												// baseMipLevel
734 			1u,												// levelCount
735 			0u,												// baseArrayLayer
736 			1u,												// layerCount
737 		},												// subresourceRange
738 	};
739 	const Unique<VkImageView>				colorAttView			(createImageView(vk, vkDevice, &colorAttViewParams));
740 
741 	// Pipeline layout
742 	const VkPipelineLayoutCreateInfo		pipelineLayoutParams	=
743 	{
744 		VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// sType
745 		DE_NULL,												// pNext
746 		(vk::VkPipelineLayoutCreateFlags)0,
747 		0u,														// setLayoutCount
748 		DE_NULL,												// pSetLayouts
749 		0u,														// pushConstantRangeCount
750 		DE_NULL,												// pPushConstantRanges
751 	};
752 	const Unique<VkPipelineLayout>			pipelineLayout			(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
753 
754 	// Shaders
755 	const Unique<VkShaderModule>			vertShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("vert"), 0));
756 	const Unique<VkShaderModule>			fragShaderModule		(createShaderModule(vk, vkDevice, context.getBinaryCollection().get("frag"), 0));
757 
758 	// Pipeline
759 	const std::vector<VkViewport>			viewports				(1, makeViewport(renderSize));
760 	const std::vector<VkRect2D>				scissors				(1, makeRect2D(renderSize));
761 
762 	const Unique<VkPipeline>				pipeline				(makeGraphicsPipeline(vk,					// const DeviceInterface&            vk
763 																						  vkDevice,				// const VkDevice                    device
764 																						  *pipelineLayout,		// const VkPipelineLayout            pipelineLayout
765 																						  *vertShaderModule,	// const VkShaderModule              vertexShaderModule
766 																						  DE_NULL,				// const VkShaderModule              tessellationControlShaderModule
767 																						  DE_NULL,				// const VkShaderModule              tessellationEvalShaderModule
768 																						  DE_NULL,				// const VkShaderModule              geometryShaderModule
769 																						  *fragShaderModule,	// const VkShaderModule              fragmentShaderModule
770 																						  *renderPass,			// const VkRenderPass                renderPass
771 																						  viewports,			// const std::vector<VkViewport>&    viewports
772 																						  scissors));			// const std::vector<VkRect2D>&      scissors
773 
774 	// Framebuffer
775 	const VkFramebufferCreateInfo			framebufferParams		=
776 	{
777 		VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,				// sType
778 		DE_NULL,												// pNext
779 		0u,														// flags
780 		*renderPass,											// renderPass
781 		1u,														// attachmentCount
782 		&*colorAttView,											// pAttachments
783 		(deUint32)renderSize.x(),								// width
784 		(deUint32)renderSize.y(),								// height
785 		1u,														// layers
786 	};
787 	const Unique<VkFramebuffer>				framebuffer				(createFramebuffer(vk, vkDevice, &framebufferParams));
788 
789 	const VkCommandPoolCreateInfo			cmdPoolParams			=
790 	{
791 		VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,					// sType
792 		DE_NULL,													// pNext
793 		VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,			// flags
794 		queueFamilyIndex,											// queueFamilyIndex
795 	};
796 	const Unique<VkCommandPool>				cmdPool					(createCommandPool(vk, vkDevice, &cmdPoolParams));
797 
798 	// Command buffer
799 	const VkCommandBufferAllocateInfo		cmdBufParams			=
800 	{
801 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,			// sType
802 		DE_NULL,												// pNext
803 		*cmdPool,												// pool
804 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,						// level
805 		1u,														// bufferCount
806 	};
807 	const Unique<VkCommandBuffer>			cmdBuf					(allocateCommandBuffer(vk, vkDevice, &cmdBufParams));
808 
809 	// Record commands
810 	beginCommandBuffer(vk, *cmdBuf);
811 
812 	{
813 		const VkMemoryBarrier		vertFlushBarrier	=
814 		{
815 			VK_STRUCTURE_TYPE_MEMORY_BARRIER,			// sType
816 			DE_NULL,									// pNext
817 			VK_ACCESS_HOST_WRITE_BIT,					// srcAccessMask
818 			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,		// dstAccessMask
819 		};
820 		const VkImageMemoryBarrier	colorAttBarrier		=
821 		{
822 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// sType
823 			DE_NULL,									// pNext
824 			0u,											// srcAccessMask
825 			(VK_ACCESS_COLOR_ATTACHMENT_READ_BIT|
826 			 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT),		// dstAccessMask
827 			VK_IMAGE_LAYOUT_UNDEFINED,					// oldLayout
828 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,	// newLayout
829 			queueFamilyIndex,							// srcQueueFamilyIndex
830 			queueFamilyIndex,							// dstQueueFamilyIndex
831 			*image,										// image
832 			{
833 				VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
834 				0u,											// baseMipLevel
835 				1u,											// levelCount
836 				0u,											// baseArrayLayer
837 				1u,											// layerCount
838 			}											// subresourceRange
839 		};
840 		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);
841 	}
842 
843 	beginRenderPass(vk, *cmdBuf, *renderPass, *framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), clearColor);
844 
845 	vk.cmdBindPipeline(*cmdBuf, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
846 	{
847 		const VkDeviceSize bindingOffset = 0;
848 		vk.cmdBindVertexBuffers(*cmdBuf, 0u, 1u, &vertexBuffer.get(), &bindingOffset);
849 	}
850 	vk.cmdDraw(*cmdBuf, 3u, 1u, 0u, 0u);
851 	endRenderPass(vk, *cmdBuf);
852 	copyImageToBuffer(vk, *cmdBuf, *image, *readImageBuffer, renderSize);
853 	endCommandBuffer(vk, *cmdBuf);
854 
855 	// Upload vertex data
856 	deMemcpy(vertexBufferMemory->getHostPtr(), &vertices[0], sizeof(vertices));
857 	flushAlloc(vk, vkDevice, *vertexBufferMemory);
858 
859 	// Submit & wait for completion
860 	submitCommandsAndWait(vk, vkDevice, queue, cmdBuf.get());
861 
862 	// Read results, render reference, compare
863 	{
864 		const tcu::TextureFormat			tcuFormat		= vk::mapVkFormat(colorFormat);
865 		const tcu::ConstPixelBufferAccess	resultAccess	(tcuFormat, renderSize.x(), renderSize.y(), 1, readImageBufferMemory->getHostPtr());
866 
867 		invalidateAlloc(vk, vkDevice, *readImageBufferMemory);
868 
869 		{
870 			tcu::TextureLevel	refImage		(tcuFormat, renderSize.x(), renderSize.y());
871 			const tcu::UVec4	threshold		(0u);
872 			const tcu::IVec3	posDeviation	(1,1,0);
873 
874 			tcu::clear(refImage.getAccess(), clearColor);
875 			renderReferenceTriangle(refImage.getAccess(), vertices, context.getDeviceProperties().limits.subPixelPrecisionBits);
876 
877 			if (tcu::intThresholdPositionDeviationCompare(context.getTestContext().getLog(),
878 														  "ComparisonResult",
879 														  "Image comparison result",
880 														  refImage.getAccess(),
881 														  resultAccess,
882 														  threshold,
883 														  posDeviation,
884 														  false,
885 														  tcu::COMPARE_LOG_RESULT))
886 				return tcu::TestStatus::pass("Rendering succeeded");
887 			else
888 				return tcu::TestStatus::fail("Image comparison failed");
889 		}
890 	}
891 
892 	return tcu::TestStatus::pass("Rendering succeeded");
893 }
894 
895 } // anonymous
896 
createSmokeTests(tcu::TestContext & testCtx)897 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& testCtx)
898 {
899 	de::MovePtr<tcu::TestCaseGroup>	smokeTests	(new tcu::TestCaseGroup(testCtx, "smoke", "Smoke Tests"));
900 
901 	addFunctionCase				(smokeTests.get(), "create_sampler",			"",	createSamplerTest);
902 	addFunctionCaseWithPrograms	(smokeTests.get(), "create_shader",				"", createShaderProgs,		createShaderModuleTest);
903 	addFunctionCaseWithPrograms	(smokeTests.get(), "triangle",					"", createTriangleProgs,	renderTriangleTest);
904 	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle",				"", createTriangleAsmProgs,	renderTriangleTest);
905 	addFunctionCaseWithPrograms	(smokeTests.get(), "asm_triangle_no_opname",	"", createProgsNoOpName,	renderTriangleTest);
906 	addFunctionCaseWithPrograms	(smokeTests.get(), "unused_resolve_attachment",	"", createTriangleProgs,	renderTriangleUnusedResolveAttachmentTest);
907 
908 	return smokeTests.release();
909 }
910 
911 } // api
912 } // vkt
913