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
51namespace vkt
52{
53namespace api
54{
55
56namespace
57{
58
59using namespace vk;
60using std::vector;
61using tcu::TestLog;
62using de::UniquePtr;
63
64tcu::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
103void 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
111tcu::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
120void 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
186void 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
198void 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
269class RefVertexShader : public rr::VertexShader
270{
271public:
272	RefVertexShader (void)
273		: rr::VertexShader(1, 0)
274	{
275		m_inputs[0].type = rr::GENERICVECTYPE_FLOAT;
276	}
277
278	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
289class RefFragmentShader : public rr::FragmentShader
290{
291public:
292	RefFragmentShader (void)
293		: rr::FragmentShader(0, 1)
294	{
295		m_outputs[0].type = rr::GENERICVECTYPE_FLOAT;
296	}
297
298	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
310void 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
332tcu::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
587struct VoidVulkanStruct
588{
589	VkStructureType sType;
590	const void*		pNext;
591};
592
593tcu::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
897tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& testCtx)
898{
899	de::MovePtr<tcu::TestCaseGroup>	smokeTests	(new tcu::TestCaseGroup(testCtx, "smoke"));
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