• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  * Copyright (c) 2016 Imagination Technologies Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *	  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Robustness Utilities
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktRobustnessUtil.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 #include "vkDefs.hpp"
28 #include "vkImageUtil.hpp"
29 #include "vkPrograms.hpp"
30 #include "vkQueryUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkTypeUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "tcuCommandLine.hpp"
36 #include "deMath.h"
37 #include <iomanip>
38 #include <limits>
39 #include <sstream>
40 
41 namespace vkt
42 {
43 namespace robustness
44 {
45 
46 using namespace vk;
47 
createRobustBufferAccessDevice(Context & context)48 Move<VkDevice> createRobustBufferAccessDevice (Context& context)
49 {
50 	const float queuePriority = 1.0f;
51 
52 	// Create a universal queue that supports graphics and compute
53 	const VkDeviceQueueCreateInfo	queueParams =
54 	{
55 		VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,	// VkStructureType				sType;
56 		DE_NULL,									// const void*					pNext;
57 		0u,											// VkDeviceQueueCreateFlags		flags;
58 		context.getUniversalQueueFamilyIndex(),		// deUint32						queueFamilyIndex;
59 		1u,											// deUint32						queueCount;
60 		&queuePriority								// const float*					pQueuePriorities;
61 	};
62 
63 	VkPhysicalDeviceFeatures enabledFeatures = context.getDeviceFeatures();
64 	enabledFeatures.robustBufferAccess = true;
65 
66 	const VkDeviceCreateInfo		deviceParams =
67 	{
68 		VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,	// VkStructureType					sType;
69 		DE_NULL,								// const void*						pNext;
70 		0u,										// VkDeviceCreateFlags				flags;
71 		1u,										// deUint32							queueCreateInfoCount;
72 		&queueParams,							// const VkDeviceQueueCreateInfo*	pQueueCreateInfos;
73 		0u,										// deUint32							enabledLayerCount;
74 		DE_NULL,								// const char* const*				ppEnabledLayerNames;
75 		0u,										// deUint32							enabledExtensionCount;
76 		DE_NULL,								// const char* const*				ppEnabledExtensionNames;
77 		&enabledFeatures						// const VkPhysicalDeviceFeatures*	pEnabledFeatures;
78 	};
79 
80 	return createCustomDevice(context.getTestContext().getCommandLine().isValidationEnabled(), context.getPlatformInterface(),
81 							  context.getInstance(), context.getInstanceInterface(), context.getPhysicalDevice(), &deviceParams);
82 }
83 
areEqual(float a,float b)84 bool areEqual (float a, float b)
85 {
86 	return deFloatAbs(a - b) <= 0.001f;
87 }
88 
isValueZero(const void * valuePtr,size_t valueSizeInBytes)89 bool isValueZero (const void* valuePtr, size_t valueSizeInBytes)
90 {
91 	const deUint8* bytePtr = reinterpret_cast<const deUint8*>(valuePtr);
92 
93 	for (size_t i = 0; i < valueSizeInBytes; i++)
94 	{
95 		if (bytePtr[i] != 0)
96 			return false;
97 	}
98 
99 	return true;
100 }
101 
isValueWithinBuffer(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)102 bool isValueWithinBuffer (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
103 {
104 	const deUint8* byteBuffer = reinterpret_cast<const deUint8*>(buffer);
105 
106 	if (bufferSize < ((VkDeviceSize)valueSizeInBytes))
107 		return false;
108 
109 	for (VkDeviceSize i = 0; i <= (bufferSize - valueSizeInBytes); i++)
110 	{
111 		if (!deMemCmp(&byteBuffer[i], valuePtr, valueSizeInBytes))
112 			return true;
113 	}
114 
115 	return false;
116 }
117 
isValueWithinBufferOrZero(const void * buffer,VkDeviceSize bufferSize,const void * valuePtr,size_t valueSizeInBytes)118 bool isValueWithinBufferOrZero (const void* buffer, VkDeviceSize bufferSize, const void* valuePtr, size_t valueSizeInBytes)
119 {
120 	return isValueWithinBuffer(buffer, bufferSize, valuePtr, valueSizeInBytes) || isValueZero(valuePtr, valueSizeInBytes);
121 }
122 
verifyOutOfBoundsVec4(const void * vecPtr,VkFormat bufferFormat)123 bool verifyOutOfBoundsVec4 (const void* vecPtr, VkFormat bufferFormat)
124 {
125 	if (isUintFormat(bufferFormat))
126 	{
127 		const deUint32* data = (deUint32*)vecPtr;
128 
129 		return data[0] == 0u
130 			&& data[1] == 0u
131 			&& data[2] == 0u
132 			&& (data[3] == 0u || data[3] == 1u || data[3] == std::numeric_limits<deUint32>::max());
133 	}
134 	else if (isIntFormat(bufferFormat))
135 	{
136 		const deInt32* data = (deInt32*)vecPtr;
137 
138 		return data[0] == 0
139 			&& data[1] == 0
140 			&& data[2] == 0
141 			&& (data[3] == 0 || data[3] == 1 || data[3] == std::numeric_limits<deInt32>::max());
142 	}
143 	else if (isFloatFormat(bufferFormat))
144 	{
145 		const float* data = (float*)vecPtr;
146 
147 		return areEqual(data[0], 0.0f)
148 			&& areEqual(data[1], 0.0f)
149 			&& areEqual(data[2], 0.0f)
150 			&& (areEqual(data[3], 0.0f) || areEqual(data[3], 1.0f));
151 	}
152 	else if (bufferFormat == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
153 	{
154 		return *((deUint32*)vecPtr) == 0xc0000000u;
155 	}
156 
157 	DE_ASSERT(false);
158 	return false;
159 }
160 
populateBufferWithTestValues(void * buffer,VkDeviceSize size,VkFormat format)161 void populateBufferWithTestValues (void* buffer, VkDeviceSize size, VkFormat format)
162 {
163 	// Assign a sequence of 32-bit values
164 	for (VkDeviceSize scalarNdx = 0; scalarNdx < size / 4; scalarNdx++)
165 	{
166 		const deUint32 valueIndex = (deUint32)(2 + scalarNdx); // Do not use 0 or 1
167 
168 		if (isUintFormat(format))
169 		{
170 			reinterpret_cast<deUint32*>(buffer)[scalarNdx] = valueIndex;
171 		}
172 		else if (isIntFormat(format))
173 		{
174 			reinterpret_cast<deInt32*>(buffer)[scalarNdx] = -deInt32(valueIndex);
175 		}
176 		else if (isFloatFormat(format))
177 		{
178 			reinterpret_cast<float*>(buffer)[scalarNdx] = float(valueIndex);
179 		}
180 		else if (format == VK_FORMAT_A2B10G10R10_UNORM_PACK32)
181 		{
182 			const deUint32	r	= ((valueIndex + 0) & ((2u << 10) - 1u));
183 			const deUint32	g	= ((valueIndex + 1) & ((2u << 10) - 1u));
184 			const deUint32	b	= ((valueIndex + 2) & ((2u << 10) - 1u));
185 			const deUint32	a	= ((valueIndex + 0) & ((2u << 2) - 1u));
186 
187 			reinterpret_cast<deUint32*>(buffer)[scalarNdx] = (a << 30) | (b << 20) | (g << 10) | r;
188 		}
189 		else
190 		{
191 			DE_ASSERT(false);
192 		}
193 	}
194 }
195 
logValue(std::ostringstream & logMsg,const void * valuePtr,VkFormat valueFormat,size_t valueSize)196 void logValue (std::ostringstream& logMsg, const void* valuePtr, VkFormat valueFormat, size_t valueSize)
197 {
198 	if (isUintFormat(valueFormat))
199 	{
200 		logMsg << *reinterpret_cast<const deUint32*>(valuePtr);
201 	}
202 	else if (isIntFormat(valueFormat))
203 	{
204 		logMsg << *reinterpret_cast<const deInt32*>(valuePtr);
205 	}
206 	else if (isFloatFormat(valueFormat))
207 	{
208 		logMsg << *reinterpret_cast<const float*>(valuePtr);
209 	}
210 	else
211 	{
212 		const deUint8*				bytePtr		= reinterpret_cast<const deUint8*>(valuePtr);
213 		const std::ios::fmtflags	streamFlags	= logMsg.flags();
214 
215 		logMsg << std::hex;
216 		for (size_t i = 0; i < valueSize; i++)
217 		{
218 			logMsg << " " << (deUint32)bytePtr[i];
219 		}
220 		logMsg.flags(streamFlags);
221 	}
222 }
223 
224 // TestEnvironment
225 
TestEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet)226 TestEnvironment::TestEnvironment (Context&				context,
227 								  VkDevice				device,
228 								  VkDescriptorSetLayout	descriptorSetLayout,
229 								  VkDescriptorSet		descriptorSet)
230 	: m_context				(context)
231 	, m_device				(device)
232 	, m_descriptorSetLayout	(descriptorSetLayout)
233 	, m_descriptorSet		(descriptorSet)
234 {
235 	const DeviceInterface& vk = context.getDeviceInterface();
236 
237 	// Create command pool
238 	{
239 		const VkCommandPoolCreateInfo commandPoolParams =
240 		{
241 			VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,		// VkStructureType			sType;
242 			DE_NULL,										// const void*				pNext;
243 			VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,			// VkCommandPoolCreateFlags	flags;
244 			context.getUniversalQueueFamilyIndex()			// deUint32					queueFamilyIndex;
245 		};
246 
247 		m_commandPool = createCommandPool(vk, m_device, &commandPoolParams);
248 	}
249 
250 	// Create command buffer
251 	{
252 		const VkCommandBufferAllocateInfo commandBufferAllocateInfo =
253 		{
254 			VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,	// VkStructureType			sType;
255 			DE_NULL,										// const void*				pNext;
256 			*m_commandPool,										// VkCommandPool			commandPool;
257 			VK_COMMAND_BUFFER_LEVEL_PRIMARY,				// VkCommandBufferLevel		level;
258 			1u,												// deUint32					bufferCount;
259 		};
260 
261 		m_commandBuffer = allocateCommandBuffer(vk, m_device, &commandBufferAllocateInfo);
262 	}
263 }
264 
getCommandBuffer(void)265 VkCommandBuffer TestEnvironment::getCommandBuffer (void)
266 {
267 	return *m_commandBuffer;
268 }
269 
270 // GraphicsEnvironment
271 
GraphicsEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet,const VertexBindings & vertexBindings,const VertexAttributes & vertexAttributes,const DrawConfig & drawConfig)272 GraphicsEnvironment::GraphicsEnvironment (Context&					context,
273 										  VkDevice					device,
274 										  VkDescriptorSetLayout		descriptorSetLayout,
275 										  VkDescriptorSet			descriptorSet,
276 										  const VertexBindings&		vertexBindings,
277 										  const VertexAttributes&	vertexAttributes,
278 										  const DrawConfig&			drawConfig)
279 
280 	: TestEnvironment		(context, device, descriptorSetLayout, descriptorSet)
281 	, m_renderSize			(16, 16)
282 	, m_colorFormat			(VK_FORMAT_R8G8B8A8_UNORM)
283 {
284 	const DeviceInterface&		vk						= context.getDeviceInterface();
285 	const deUint32				queueFamilyIndex		= context.getUniversalQueueFamilyIndex();
286 	const VkComponentMapping	componentMappingRGBA	= { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
287 	SimpleAllocator				memAlloc				(vk, m_device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
288 
289 	// Create color image and view
290 	{
291 		const VkImageCreateInfo colorImageParams =
292 		{
293 			VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,										// VkStructureType			sType;
294 			DE_NULL,																	// const void*				pNext;
295 			0u,																			// VkImageCreateFlags		flags;
296 			VK_IMAGE_TYPE_2D,															// VkImageType				imageType;
297 			m_colorFormat,																// VkFormat					format;
298 			{ (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },				// VkExtent3D				extent;
299 			1u,																			// deUint32					mipLevels;
300 			1u,																			// deUint32					arrayLayers;
301 			VK_SAMPLE_COUNT_1_BIT,														// VkSampleCountFlagBits	samples;
302 			VK_IMAGE_TILING_OPTIMAL,													// VkImageTiling			tiling;
303 			VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,		// VkImageUsageFlags		usage;
304 			VK_SHARING_MODE_EXCLUSIVE,													// VkSharingMode			sharingMode;
305 			1u,																			// deUint32					queueFamilyIndexCount;
306 			&queueFamilyIndex,															// const deUint32*			pQueueFamilyIndices;
307 			VK_IMAGE_LAYOUT_UNDEFINED													// VkImageLayout			initialLayout;
308 		};
309 
310 		m_colorImage			= createImage(vk, m_device, &colorImageParams);
311 		m_colorImageAlloc		= memAlloc.allocate(getImageMemoryRequirements(vk, m_device, *m_colorImage), MemoryRequirement::Any);
312 		VK_CHECK(vk.bindImageMemory(m_device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
313 
314 		const VkImageViewCreateInfo colorAttachmentViewParams =
315 		{
316 			VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,			// VkStructureType			sType;
317 			DE_NULL,											// const void*				pNext;
318 			0u,													// VkImageViewCreateFlags	flags;
319 			*m_colorImage,										// VkImage					image;
320 			VK_IMAGE_VIEW_TYPE_2D,								// VkImageViewType			viewType;
321 			m_colorFormat,										// VkFormat					format;
322 			componentMappingRGBA,								// VkComponentMapping		components;
323 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }		// VkImageSubresourceRange	subresourceRange;
324 		};
325 
326 		m_colorAttachmentView = createImageView(vk, m_device, &colorAttachmentViewParams);
327 	}
328 
329 	// Create render pass
330 	m_renderPass = makeRenderPass(vk, m_device, m_colorFormat);
331 
332 	// Create framebuffer
333 	{
334 		const VkFramebufferCreateInfo framebufferParams =
335 		{
336 			VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,			// VkStructureType			sType;
337 			DE_NULL,											// const void*				pNext;
338 			0u,													// VkFramebufferCreateFlags	flags;
339 			*m_renderPass,										// VkRenderPass				renderPass;
340 			1u,													// deUint32					attachmentCount;
341 			&m_colorAttachmentView.get(),						// const VkImageView*		pAttachments;
342 			(deUint32)m_renderSize.x(),							// deUint32					width;
343 			(deUint32)m_renderSize.y(),							// deUint32					height;
344 			1u													// deUint32					layers;
345 		};
346 
347 		m_framebuffer = createFramebuffer(vk, m_device, &framebufferParams);
348 	}
349 
350 	// Create pipeline layout
351 	{
352 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
353 		{
354 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,		// VkStructureType				sType;
355 			DE_NULL,											// const void*					pNext;
356 			0u,													// VkPipelineLayoutCreateFlags	flags;
357 			1u,													// deUint32						setLayoutCount;
358 			&m_descriptorSetLayout,								// const VkDescriptorSetLayout*	pSetLayouts;
359 			0u,													// deUint32						pushConstantRangeCount;
360 			DE_NULL												// const VkPushConstantRange*	pPushConstantRanges;
361 		};
362 
363 		m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams);
364 	}
365 
366 	m_vertexShaderModule	= createShaderModule(vk, m_device, m_context.getBinaryCollection().get("vertex"), 0);
367 	m_fragmentShaderModule	= createShaderModule(vk, m_device, m_context.getBinaryCollection().get("fragment"), 0);
368 
369 	// Create pipeline
370 	{
371 		const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
372 		{
373 			VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType							sType;
374 			DE_NULL,														// const void*								pNext;
375 			0u,																// VkPipelineVertexInputStateCreateFlags	flags;
376 			(deUint32)vertexBindings.size(),								// deUint32									vertexBindingDescriptionCount;
377 			vertexBindings.data(),											// const VkVertexInputBindingDescription*	pVertexBindingDescriptions;
378 			(deUint32)vertexAttributes.size(),								// deUint32									vertexAttributeDescriptionCount;
379 			vertexAttributes.data()											// const VkVertexInputAttributeDescription*	pVertexAttributeDescriptions;
380 		};
381 
382 		const std::vector<VkViewport>	viewports	(1, makeViewport(m_renderSize));
383 		const std::vector<VkRect2D>		scissors	(1, makeRect2D(m_renderSize));
384 
385 		m_graphicsPipeline = makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
386 												  m_device,								// const VkDevice                                device
387 												  *m_pipelineLayout,					// const VkPipelineLayout                        pipelineLayout
388 												  *m_vertexShaderModule,				// const VkShaderModule                          vertexShaderModule
389 												  DE_NULL,								// const VkShaderModule                          tessellationControlShaderModule
390 												  DE_NULL,								// const VkShaderModule                          tessellationEvalShaderModule
391 												  DE_NULL,								// const VkShaderModule                          geometryShaderModule
392 												  *m_fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
393 												  *m_renderPass,						// const VkRenderPass                            renderPass
394 												  viewports,							// const std::vector<VkViewport>&                viewports
395 												  scissors,								// const std::vector<VkRect2D>&                  scissors
396 												  VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,	// const VkPrimitiveTopology                     topology
397 												  0u,									// const deUint32                                subpass
398 												  0u,									// const deUint32                                patchControlPoints
399 												  &vertexInputStateParams);				// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
400 	}
401 
402 	// Record commands
403 	{
404 		const VkImageMemoryBarrier imageLayoutBarrier =
405 		{
406 			VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,					// VkStructureType			sType;
407 			DE_NULL,												// const void*				pNext;
408 			(VkAccessFlags)0,										// VkAccessFlags			srcAccessMask;
409 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
410 			VK_IMAGE_LAYOUT_UNDEFINED,								// VkImageLayout			oldLayout;
411 			VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,				// VkImageLayout			newLayout;
412 			VK_QUEUE_FAMILY_IGNORED,								// uint32_t					srcQueueFamilyIndex;
413 			VK_QUEUE_FAMILY_IGNORED,								// uint32_t					dstQueueFamilyIndex;
414 			*m_colorImage,											// VkImage					image;
415 			{ VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }			// VkImageSubresourceRange	subresourceRange;
416 		};
417 
418 		beginCommandBuffer(vk, *m_commandBuffer, 0u);
419 		{
420 			vk.cmdPipelineBarrier(*m_commandBuffer,
421 								  VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
422 								  VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
423 								  (VkDependencyFlags)0,
424 								  0u, DE_NULL,
425 								  0u, DE_NULL,
426 								  1u, &imageLayoutBarrier);
427 
428 			beginRenderPass(vk, *m_commandBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f));
429 			{
430 				const std::vector<VkDeviceSize> vertexBufferOffsets(drawConfig.vertexBuffers.size(), 0ull);
431 
432 				vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
433 				vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL);
434 				vk.cmdBindVertexBuffers(*m_commandBuffer, 0, (deUint32)drawConfig.vertexBuffers.size(), drawConfig.vertexBuffers.data(), vertexBufferOffsets.data());
435 
436 				if (drawConfig.indexBuffer == DE_NULL || drawConfig.indexCount == 0)
437 				{
438 					vk.cmdDraw(*m_commandBuffer, drawConfig.vertexCount, drawConfig.instanceCount, 0, 0);
439 				}
440 				else
441 				{
442 					vk.cmdBindIndexBuffer(*m_commandBuffer, drawConfig.indexBuffer, 0, VK_INDEX_TYPE_UINT32);
443 					vk.cmdDrawIndexed(*m_commandBuffer, drawConfig.indexCount, drawConfig.instanceCount, 0, 0, 0);
444 				}
445 			}
446 			endRenderPass(vk, *m_commandBuffer);
447 		}
448 		endCommandBuffer(vk, *m_commandBuffer);
449 	}
450 }
451 
452 // ComputeEnvironment
453 
ComputeEnvironment(Context & context,VkDevice device,VkDescriptorSetLayout descriptorSetLayout,VkDescriptorSet descriptorSet)454 ComputeEnvironment::ComputeEnvironment (Context&				context,
455 										VkDevice				device,
456 										VkDescriptorSetLayout	descriptorSetLayout,
457 										VkDescriptorSet			descriptorSet)
458 
459 	: TestEnvironment	(context, device, descriptorSetLayout, descriptorSet)
460 {
461 	const DeviceInterface& vk = context.getDeviceInterface();
462 
463 	// Create pipeline layout
464 	{
465 		const VkPipelineLayoutCreateInfo pipelineLayoutParams =
466 		{
467 			VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,			// VkStructureType					sType;
468 			DE_NULL,												// const void*						pNext;
469 			0u,														// VkPipelineLayoutCreateFlags		flags;
470 			1u,														// deUint32							setLayoutCount;
471 			&m_descriptorSetLayout,									// const VkDescriptorSetLayout*		pSetLayouts;
472 			0u,														// deUint32							pushConstantRangeCount;
473 			DE_NULL													// const VkPushConstantRange*		pPushConstantRanges;
474 		};
475 
476 		m_pipelineLayout = createPipelineLayout(vk, m_device, &pipelineLayoutParams);
477 	}
478 
479 	// Create compute pipeline
480 	{
481 		m_computeShaderModule = createShaderModule(vk, m_device, m_context.getBinaryCollection().get("compute"), 0);
482 
483 		const VkPipelineShaderStageCreateInfo computeStageParams =
484 		{
485 			VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
486 			DE_NULL,												// const void*							pNext;
487 			0u,														// VkPipelineShaderStageCreateFlags		flags;
488 			VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits				stage;
489 			*m_computeShaderModule,									// VkShaderModule						module;
490 			"main",													// const char*							pName;
491 			DE_NULL,												// const VkSpecializationInfo*			pSpecializationInfo;
492 		};
493 
494 		const VkComputePipelineCreateInfo computePipelineParams =
495 		{
496 			VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,			// VkStructureType						sType;
497 			DE_NULL,												// const void*							pNext;
498 			0u,														// VkPipelineCreateFlags				flags;
499 			computeStageParams,										// VkPipelineShaderStageCreateInfo		stage;
500 			*m_pipelineLayout,										// VkPipelineLayout						layout;
501 			DE_NULL,												// VkPipeline							basePipelineHandle;
502 			0u														// deInt32								basePipelineIndex;
503 		};
504 
505 		m_computePipeline = createComputePipeline(vk, m_device, DE_NULL, &computePipelineParams);
506 	}
507 
508 	// Record commands
509 	{
510 		beginCommandBuffer(vk, *m_commandBuffer, 0u);
511 		vk.cmdBindPipeline(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline);
512 		vk.cmdBindDescriptorSets(*m_commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0, 1, &m_descriptorSet, 0, DE_NULL);
513 		vk.cmdDispatch(*m_commandBuffer, 32, 32, 1);
514 		endCommandBuffer(vk, *m_commandBuffer);
515 	}
516 }
517 
518 } // robustness
519 } // vkt
520