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