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