• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Samsung Electronics Co., 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 Protected Memory Utility methods
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemUtils.hpp"
26 #include "vktCustomInstancesDevices.hpp"
27 
28 #include "deString.h"
29 #include "deRandom.hpp"
30 
31 #include "vkDeviceUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkDebugReportUtil.hpp"
35 #include "vkApiVersion.hpp"
36 #include "vkObjUtil.hpp"
37 #include "vkSafetyCriticalUtil.hpp"
38 
39 #include "vkPlatform.hpp"
40 #include "vktProtectedMemContext.hpp"
41 #include "vkWsiUtil.hpp"
42 #include "vkObjUtil.hpp"
43 
44 namespace vkt
45 {
46 
47 using namespace vk;
48 
49 namespace ProtectedMem
50 {
51 
52 typedef std::vector<vk::VkExtensionProperties> Extensions;
53 
makeProtectedMemInstance(vkt::Context & context,const std::vector<std::string> & extraExtensions)54 CustomInstance makeProtectedMemInstance (vkt::Context& context, const std::vector<std::string>& extraExtensions)
55 {
56 	const PlatformInterface&	vkp = context.getPlatformInterface();
57 	const Extensions			supportedExtensions(vk::enumerateInstanceExtensionProperties(vkp, DE_NULL));
58 	std::vector<std::string>	requiredExtensions = extraExtensions;
59 
60 	deUint32 apiVersion = context.getUsedApiVersion();
61 	if (!isCoreInstanceExtension(apiVersion, "VK_KHR_get_physical_device_properties2"))
62 		requiredExtensions.push_back("VK_KHR_get_physical_device_properties2");
63 
64 	// extract extension names
65 	std::vector<std::string> extensions;
66 	for (const auto& e : supportedExtensions)
67 		extensions.push_back(e.extensionName);
68 
69 	for (const auto& extName : requiredExtensions)
70 	{
71 		if (!isInstanceExtensionSupported(apiVersion, extensions, extName))
72 			TCU_THROW(NotSupportedError, (extName + " is not supported").c_str());
73 	}
74 
75 	return createCustomInstanceWithExtensions(context, requiredExtensions);
76 }
77 
checkProtectedQueueSupport(Context & context)78 void checkProtectedQueueSupport (Context& context)
79 {
80 #ifdef NOT_PROTECTED
81 	return;
82 #endif
83 
84 	const vk::InstanceInterface&				vkd				= context.getInstanceInterface();
85 	vk::VkPhysicalDevice						physDevice		= context.getPhysicalDevice();
86 	std::vector<vk::VkQueueFamilyProperties>	properties;
87 	deUint32									numFamilies		= 0;
88 
89 	vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, DE_NULL);
90 	DE_ASSERT(numFamilies > 0);
91 	properties.resize(numFamilies);
92 
93 	vkd.getPhysicalDeviceQueueFamilyProperties(physDevice, &numFamilies, properties.data());
94 
95 	for (auto prop: properties)
96 		if (prop.queueFlags & vk::VK_QUEUE_PROTECTED_BIT)
97 			return;
98 
99 	TCU_THROW(NotSupportedError, "No protected queue found.");
100 }
101 
chooseProtectedMemQueueFamilyIndex(const vk::InstanceDriver & vkd,vk::VkPhysicalDevice physicalDevice,vk::VkSurfaceKHR surface)102 deUint32 chooseProtectedMemQueueFamilyIndex	(const vk::InstanceDriver&	vkd,
103 											 vk::VkPhysicalDevice		physicalDevice,
104 											 vk::VkSurfaceKHR			surface)
105 {
106 	std::vector<vk::VkQueueFamilyProperties>	properties;
107 	deUint32									numFamilies		= 0;
108 
109 	vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, DE_NULL);
110 	DE_ASSERT(numFamilies > 0);
111 	properties.resize(numFamilies);
112 
113 	vkd.getPhysicalDeviceQueueFamilyProperties(physicalDevice, &numFamilies, properties.data());
114 
115 	// Get a universal protected queue family index
116 	vk::VkQueueFlags	requiredFlags = vk::VK_QUEUE_GRAPHICS_BIT
117 										| vk::VK_QUEUE_COMPUTE_BIT
118 #ifndef NOT_PROTECTED
119 										| vk::VK_QUEUE_PROTECTED_BIT
120 #endif
121 										;
122 	for (size_t idx = 0; idx < properties.size(); ++idx)
123 	{
124 		vk::VkQueueFlags	flags = properties[idx].queueFlags;
125 
126 		if (surface != DE_NULL
127 			&& vk::wsi::getPhysicalDeviceSurfaceSupport(vkd, physicalDevice, (deUint32)idx, surface) == VK_FALSE)
128 			continue; // Skip the queue family index if it does not support the surface
129 
130 		if ((flags & requiredFlags) == requiredFlags)
131 			return (deUint32)idx;
132 	}
133 
134 	TCU_THROW(NotSupportedError, "No matching universal protected queue found");
135 }
136 
makeProtectedMemDevice(const vk::PlatformInterface & vkp,vk::VkInstance instance,const vk::InstanceDriver & vkd,vk::VkPhysicalDevice physicalDevice,const deUint32 queueFamilyIndex,const deUint32 apiVersion,const std::vector<std::string> & extraExtensions,de::SharedPtr<vk::ResourceInterface> resourceInterface,const tcu::CommandLine & cmdLine)137 vk::Move<vk::VkDevice> makeProtectedMemDevice	(const vk::PlatformInterface&		vkp,
138 												 vk::VkInstance						instance,
139 												 const vk::InstanceDriver&			vkd,
140 												 vk::VkPhysicalDevice				physicalDevice,
141 												 const deUint32						queueFamilyIndex,
142 												 const deUint32						apiVersion,
143 												 const std::vector<std::string>&	extraExtensions,
144 #ifdef CTS_USES_VULKANSC
145 												 de::SharedPtr<vk::ResourceInterface> resourceInterface,
146 #endif // CTS_USES_VULKANSC
147 												 const tcu::CommandLine&		cmdLine)
148 {
149 	const Extensions					supportedExtensions	(vk::enumerateDeviceExtensionProperties(vkd, physicalDevice, DE_NULL));
150 	std::vector<std::string>			requiredExtensions;
151 	std::vector<std::string>			extensions			= extraExtensions;
152 
153 	if (apiVersion < VK_API_VERSION_1_1)
154 		TCU_THROW(NotSupportedError, "Vulkan 1.1 is not supported");
155 
156 	bool								useYCbCr			= de::contains(extensions.begin(), extensions.end(), std::string("VK_KHR_sampler_ycbcr_conversion"));
157 #ifndef CTS_USES_VULKANSC
158 	bool								useProtectedAccess	= de::contains(extensions.begin(), extensions.end(), std::string("VK_EXT_pipeline_protected_access"));
159 #endif
160 
161 	// Check if the physical device supports the protected memory extension name
162 	for (deUint32 ndx = 0; ndx < extensions.size(); ++ndx)
163 	{
164 		bool notInCore = !isCoreDeviceExtension(apiVersion, extensions[ndx]);
165 		if (notInCore && !isExtensionStructSupported(supportedExtensions.begin(), supportedExtensions.end(), RequiredExtension(extensions[ndx])))
166 			TCU_THROW(NotSupportedError, (extensions[ndx] + " is not supported").c_str());
167 
168 		if (notInCore)
169 			requiredExtensions.push_back(extensions[ndx]);
170 	}
171 
172 	std::vector<const char*>			enabledExts			(requiredExtensions.size());
173 	for (size_t idx = 0; idx < requiredExtensions.size(); ++idx)
174 	{
175 		enabledExts[idx] = requiredExtensions[idx].c_str();
176 	}
177 
178 #ifndef CTS_USES_VULKANSC
179 	vk::VkPhysicalDevicePipelineProtectedAccessFeaturesEXT	protectedAccessFeature =
180 	{
181 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PIPELINE_PROTECTED_ACCESS_FEATURES_EXT,
182 		DE_NULL,
183 		VK_FALSE
184 	};
185 #endif
186 
187 	vk::VkPhysicalDeviceSamplerYcbcrConversionFeatures		ycbcrFeature	=
188 	{
189 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
190 #ifndef CTS_USES_VULKANSC
191 		&protectedAccessFeature,
192 #else
193 		DE_NULL,
194 #endif
195 		VK_FALSE
196 	};
197 	// Check if the protected memory can be enabled on the physical device.
198 	vk::VkPhysicalDeviceProtectedMemoryFeatures	protectedFeature =
199 	{
200 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES,	// sType
201 		&ycbcrFeature,														// pNext
202 		VK_FALSE															// protectedMemory
203 	};
204 	vk::VkPhysicalDeviceFeatures					features;
205 	deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
206 
207 	vk::VkPhysicalDeviceFeatures2				featuresExt		=
208 	{
209 		vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,					// sType
210 		&protectedFeature,													// pNext
211 		features
212 	};
213 
214 	vkd.getPhysicalDeviceFeatures2(physicalDevice, &featuresExt);
215 
216 #ifndef NOT_PROTECTED
217 	if (protectedFeature.protectedMemory == VK_FALSE)
218 		TCU_THROW(NotSupportedError, "Protected Memory feature not supported by the device");
219 #endif
220 
221 	if (useYCbCr && !ycbcrFeature.samplerYcbcrConversion)
222 		TCU_THROW(NotSupportedError, "VK_KHR_sampler_ycbcr_conversion is not supported");
223 
224 #ifndef CTS_USES_VULKANSC
225 	if (useProtectedAccess && !protectedAccessFeature.pipelineProtectedAccess)
226 		TCU_THROW(NotSupportedError, "VK_EXT_pipeline_protected_access is not supported");
227 #endif
228 
229 	const float							queuePriorities[]	= { 1.0f };
230 	const vk::VkDeviceQueueCreateInfo	queueInfos[]		=
231 	{
232 		{
233 			vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
234 			DE_NULL,
235 #ifndef NOT_PROTECTED
236 			(vk::VkDeviceQueueCreateFlags)vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,
237 #else
238 			(vk::VkDeviceQueueCreateFlags)0u,
239 #endif
240 			queueFamilyIndex,
241 			DE_LENGTH_OF_ARRAY(queuePriorities),
242 			queuePriorities
243 		}
244 	};
245 
246 	void* pNext												= &featuresExt;
247 #ifdef CTS_USES_VULKANSC
248 	VkDeviceObjectReservationCreateInfo memReservationInfo	= cmdLine.isSubProcess() ? resourceInterface->getStatMax() : resetDeviceObjectReservationCreateInfo();
249 	memReservationInfo.pNext								= pNext;
250 	pNext													= &memReservationInfo;
251 
252 	VkPhysicalDeviceVulkanSC10Features sc10Features			= createDefaultSC10Features();
253 	sc10Features.pNext										= pNext;
254 	pNext													= &sc10Features;
255 
256 	VkPipelineCacheCreateInfo			pcCI;
257 	std::vector<VkPipelinePoolSize>		poolSizes;
258 	if (cmdLine.isSubProcess())
259 	{
260 		if (resourceInterface->getCacheDataSize() > 0)
261 		{
262 			pcCI =
263 			{
264 				VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,	// VkStructureType				sType;
265 				DE_NULL,										// const void*					pNext;
266 				VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
267 					VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT,	// VkPipelineCacheCreateFlags	flags;
268 				resourceInterface->getCacheDataSize(),			// deUintptr					initialDataSize;
269 				resourceInterface->getCacheData()				// const void*					pInitialData;
270 			};
271 			memReservationInfo.pipelineCacheCreateInfoCount		= 1;
272 			memReservationInfo.pPipelineCacheCreateInfos		= &pcCI;
273 		}
274 
275 		poolSizes							= resourceInterface->getPipelinePoolSizes();
276 		if (!poolSizes.empty())
277 		{
278 			memReservationInfo.pipelinePoolSizeCount		= deUint32(poolSizes.size());
279 			memReservationInfo.pPipelinePoolSizes			= poolSizes.data();
280 		}
281 	}
282 #endif // CTS_USES_VULKANSC
283 
284 	const vk::VkDeviceCreateInfo		deviceParams		=
285 	{
286 		vk::VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,						// sType
287 		pNext,															// pNext
288 		(vk::VkDeviceCreateFlags)0,										// flags
289 		DE_LENGTH_OF_ARRAY(queueInfos),									// queueCreateInfosCount
290 		&queueInfos[0],													// pQueueCreateInfos
291 		0u,																// enabledLayerCount
292 		DE_NULL,														// pEnabledLayerNames
293 		(deUint32)requiredExtensions.size(),							// enabledExtensionCount
294 		requiredExtensions.empty() ? DE_NULL : &enabledExts[0],			// pEnabledExtensionNames
295 		DE_NULL															// pEnabledFeatures
296 	};
297 
298 	return createCustomDevice(cmdLine.isValidationEnabled(), vkp, instance, vkd, physicalDevice, &deviceParams, DE_NULL);
299 }
300 
getProtectedQueue(const vk::DeviceInterface & vk,vk::VkDevice device,const deUint32 queueFamilyIndex,const deUint32 queueIdx)301 vk::VkQueue getProtectedQueue	(const vk::DeviceInterface&	vk,
302 								 vk::VkDevice				device,
303 								 const deUint32				queueFamilyIndex,
304 								 const deUint32				queueIdx)
305 {
306 	const vk::VkDeviceQueueInfo2	queueInfo	=
307 	{
308 		vk::VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2,		// sType
309 		DE_NULL,										// pNext
310 		vk::VK_DEVICE_QUEUE_CREATE_PROTECTED_BIT,		// flags
311 		queueFamilyIndex,								// queueFamilyIndex
312 		queueIdx,										// queueIndex
313 	};
314 
315 	(void)queueInfo;
316 	vk::VkQueue						queue		=
317 #ifndef NOT_PROTECTED
318 													vk::getDeviceQueue2(vk, device, &queueInfo);
319 #else
320 													vk::getDeviceQueue(vk, device, queueFamilyIndex, 0);
321 #endif
322 
323 	if (queue == DE_NULL)
324 		TCU_THROW(TestError, "Unable to get a protected queue");
325 
326 	return queue;
327 }
328 
createImage2D(ProtectedContext & context,ProtectionMode protectionMode,const deUint32 queueFamilyIdx,deUint32 width,deUint32 height,vk::VkFormat format,vk::VkImageUsageFlags usageFlags)329 de::MovePtr<vk::ImageWithMemory>	createImage2D		(ProtectedContext&		context,
330 														 ProtectionMode			protectionMode,
331 														 const deUint32			queueFamilyIdx,
332 														 deUint32				width,
333 														 deUint32				height,
334 														 vk::VkFormat			format,
335 														 vk::VkImageUsageFlags	usageFlags)
336 {
337 	const vk::DeviceInterface&	vk			= context.getDeviceInterface();
338 	const vk::VkDevice&			device		= context.getDevice();
339 	vk::Allocator&				allocator	= context.getDefaultAllocator();
340 
341 #ifndef NOT_PROTECTED
342 	deUint32					flags		= (protectionMode == PROTECTION_ENABLED)
343 												? vk::VK_IMAGE_CREATE_PROTECTED_BIT
344 												: (vk::VkImageCreateFlagBits)0u;
345 #else
346 	DE_UNREF(protectionMode);
347 	deUint32					flags		= 0u;
348 #endif
349 
350 	const vk::VkImageCreateInfo	params		=
351 	{
352 		vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType			stype
353 		DE_NULL,										// const void*				pNext
354 		(vk::VkImageCreateFlags)flags,					// VkImageCreateFlags		flags
355 		vk::VK_IMAGE_TYPE_2D,							// VkImageType				imageType
356 		format,											// VkFormat					format
357 		{ width, height, 1 },							// VkExtent3D				extent
358 		1u,												// deUint32					mipLevels
359 		1u,												// deUint32					arrayLayers
360 		vk::VK_SAMPLE_COUNT_1_BIT,						// VkSampleCountFlagBits	samples
361 		vk::VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling			tiling
362 		usageFlags,										// VkImageUsageFlags		usage
363 		vk::VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode			sharingMode
364 		1u,												// deUint32					queueFamilyIndexCount
365 		&queueFamilyIdx,								// const deUint32*			pQueueFamilyIndices
366 		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			initialLayout
367 	};
368 
369 #ifndef NOT_PROTECTED
370 	vk::MemoryRequirement		memReq		= (protectionMode == PROTECTION_ENABLED)
371 												? vk::MemoryRequirement::Protected
372 												: vk::MemoryRequirement::Any;
373 #else
374 	vk::MemoryRequirement		memReq		= vk::MemoryRequirement::Any;
375 #endif
376 
377 	return de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, allocator, params, memReq));
378 }
379 
makeBuffer(ProtectedContext & context,ProtectionMode protectionMode,const deUint32 queueFamilyIdx,deUint32 size,vk::VkBufferUsageFlags usageFlags,vk::MemoryRequirement memReq)380 de::MovePtr<vk::BufferWithMemory> makeBuffer (ProtectedContext&			context,
381 											  ProtectionMode			protectionMode,
382 											  const deUint32			queueFamilyIdx,
383 											  deUint32					size,
384 											  vk::VkBufferUsageFlags	usageFlags,
385 											  vk::MemoryRequirement		memReq)
386 {
387 	const vk::DeviceInterface&		vk			= context.getDeviceInterface();
388 	const vk::VkDevice&				device		= context.getDevice();
389 	vk::Allocator&					allocator	= context.getDefaultAllocator();
390 
391 #ifndef NOT_PROTECTED
392 	deUint32						flags		= (protectionMode == PROTECTION_ENABLED)
393 													? vk::VK_BUFFER_CREATE_PROTECTED_BIT
394 													: (vk::VkBufferCreateFlagBits)0u;
395 	vk::MemoryRequirement			requirement	= memReq;
396 #else
397 	DE_UNREF(protectionMode);
398 	deUint32						flags		= 0u;
399 	vk::MemoryRequirement			requirement	= memReq & (
400 													vk::MemoryRequirement::HostVisible
401 													| vk::MemoryRequirement::Coherent
402 													| vk::MemoryRequirement::LazilyAllocated);
403 #endif
404 
405 	const vk::VkBufferCreateInfo	params		=
406 	{
407 		vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,	// sType
408 		DE_NULL,									// pNext
409 		(vk::VkBufferCreateFlags)flags,				// flags
410 		(vk::VkDeviceSize)size,						// size
411 		usageFlags,									// usage
412 		vk::VK_SHARING_MODE_EXCLUSIVE,				// sharingMode
413 		1u,											// queueFamilyCount
414 		&queueFamilyIdx,							// pQueueFamilyIndices
415 	};
416 
417 	return de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory(vk, device, allocator, params, requirement));
418 }
419 
createImageView(ProtectedContext & context,vk::VkImage image,vk::VkFormat format)420 vk::Move<vk::VkImageView> createImageView (ProtectedContext& context, vk::VkImage image, vk::VkFormat format)
421 {
422 	const vk::VkImageViewCreateInfo params =
423 	{
424 		vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,		// sType
425 		DE_NULL,											// pNext
426 		0u,													// flags
427 		image,												// image
428 		vk::VK_IMAGE_VIEW_TYPE_2D,							// viewType
429 		format,												// format
430 		vk::makeComponentMappingRGBA(),						// components
431 		{ vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u,1u },	// subresourceRange
432 	};
433 
434 	return vk::createImageView(context.getDeviceInterface(), context.getDevice(), &params);
435 }
436 
createRenderPass(ProtectedContext & context,vk::VkFormat format)437 vk::Move<vk::VkRenderPass> createRenderPass (ProtectedContext& context, vk::VkFormat format)
438 {
439 	const vk::VkDevice					vkDevice				= context.getDevice();
440 	const vk::DeviceInterface&			vk						= context.getDeviceInterface();
441 
442 	return vk::makeRenderPass(vk, vkDevice, format);
443 }
444 
createFramebuffer(ProtectedContext & context,deUint32 width,deUint32 height,vk::VkRenderPass renderPass,vk::VkImageView colorImageView)445 vk::Move<vk::VkFramebuffer> createFramebuffer (ProtectedContext& context, deUint32 width, deUint32 height,
446 												vk::VkRenderPass renderPass, vk::VkImageView colorImageView)
447 {
448 	const vk::VkDevice					vkDevice			= context.getDevice();
449 	const vk::DeviceInterface&			vk					= context.getDeviceInterface();
450 
451 	const vk::VkFramebufferCreateInfo	framebufferParams	=
452 	{
453 		vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,	// VkStructureType			sType;
454 		DE_NULL,										// const void*				pNext;
455 		0u,												// VkFramebufferCreateFlags	flags;
456 		renderPass,										// VkRenderPass				renderPass;
457 		1u,												// deUint32					attachmentCount;
458 		&colorImageView,								// const VkImageView*		pAttachments;
459 		width,											// deUint32					width;
460 		height,											// deUint32					height;
461 		1u												// deUint32					layers;
462 	};
463 
464 	return vk::createFramebuffer(vk, vkDevice, &framebufferParams);
465 }
466 
467 
createPipelineLayout(ProtectedContext & context,deUint32 layoutCount,vk::VkDescriptorSetLayout * setLayouts)468 vk::Move<vk::VkPipelineLayout> createPipelineLayout (ProtectedContext& context, deUint32 layoutCount, vk::VkDescriptorSetLayout* setLayouts)
469 {
470 	const vk::VkPipelineLayoutCreateInfo	params	=
471 	{
472 		vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,	// sType
473 		DE_NULL,											// pNext
474 		0u,													// flags
475 		layoutCount,										// setLayoutCount
476 		setLayouts,											// pSetLayouts
477 		0u,													// pushConstantRangeCount
478 		DE_NULL,											// pPushContantRanges
479 	};
480 
481 	return vk::createPipelineLayout(context.getDeviceInterface(), context.getDevice(), &params);
482 }
483 
beginSecondaryCommandBuffer(const vk::DeviceInterface & vk,const vk::VkCommandBuffer secondaryCmdBuffer,const vk::VkCommandBufferInheritanceInfo bufferInheritanceInfo)484 void beginSecondaryCommandBuffer (const vk::DeviceInterface&				vk,
485 								  const vk::VkCommandBuffer					secondaryCmdBuffer,
486 								  const vk::VkCommandBufferInheritanceInfo	bufferInheritanceInfo)
487 {
488 	const vk::VkCommandBufferUsageFlags	flags		= bufferInheritanceInfo.renderPass != DE_NULL
489 													  ? (vk::VkCommandBufferUsageFlags)vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT
490 													  : (vk::VkCommandBufferUsageFlags)0u;
491 	const vk::VkCommandBufferBeginInfo	beginInfo	=
492 	{
493 		vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,			// sType
494 		DE_NULL,													// pNext
495 		flags,														// flags
496 		&bufferInheritanceInfo,										// pInheritanceInfo
497 	};
498 	VK_CHECK(vk.beginCommandBuffer(secondaryCmdBuffer, &beginInfo));
499 }
500 
queueSubmit(ProtectedContext & context,ProtectionMode protectionMode,vk::VkQueue queue,vk::VkCommandBuffer cmdBuffer,vk::VkFence fence,deUint64 timeout)501 vk::VkResult queueSubmit (ProtectedContext&		context,
502 						  ProtectionMode		protectionMode,
503 						  vk::VkQueue			queue,
504 						  vk::VkCommandBuffer	cmdBuffer,
505 						  vk::VkFence			fence,
506 						  deUint64				timeout)
507 {
508 	const vk::DeviceInterface&			vk			= context.getDeviceInterface();
509 	const vk::VkDevice&					device		= context.getDevice();
510 
511 	// Basic submit info
512 	vk::VkSubmitInfo					submitInfo	=
513 	{
514 		vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,			// sType
515 		DE_NULL,									// pNext
516 		0u,											// waitSemaphoreCount
517 		DE_NULL,									// pWaitSempahores
518 		(const vk::VkPipelineStageFlags*)DE_NULL,	// stageFlags
519 		1u,											// commandBufferCount
520 		&cmdBuffer,									// pCommandBuffers
521 		0u,											// signalSemaphoreCount
522 		DE_NULL,									// pSignalSemaphores
523 	};
524 
525 #ifndef NOT_PROTECTED
526 	// Protected extension submit info
527 	const vk::VkProtectedSubmitInfo		protectedInfo	=
528 	{
529 		vk::VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO,		// sType
530 		DE_NULL,											// pNext
531 		VK_TRUE,											// protectedSubmit
532 	};
533 	if (protectionMode == PROTECTION_ENABLED) {
534 		submitInfo.pNext = &protectedInfo;
535 	}
536 #else
537 	DE_UNREF(protectionMode);
538 #endif
539 
540 	VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, fence));
541 	return vk.waitForFences(device, 1u, &fence, DE_TRUE, timeout);
542 }
543 
makeSampler(const vk::DeviceInterface & vk,const vk::VkDevice & device)544 vk::Move<vk::VkSampler> makeSampler (const vk::DeviceInterface& vk, const vk::VkDevice& device)
545 {
546 	const vk::VkSamplerCreateInfo createInfo =
547 	{
548 		vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
549 		DE_NULL,
550 		0u,
551 
552 		vk::VK_FILTER_NEAREST,
553 		vk::VK_FILTER_NEAREST,
554 
555 		vk::VK_SAMPLER_MIPMAP_MODE_LINEAR,
556 		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
557 		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
558 		vk::VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
559 		0.0f,
560 		VK_FALSE,
561 		1.0f,
562 		VK_FALSE,
563 		vk::VK_COMPARE_OP_ALWAYS,
564 		0.0f,
565 		0.0f,
566 		vk::VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
567 		VK_FALSE
568 	};
569 
570 	return vk::createSampler(vk, device, &createInfo);
571 }
572 
makeCommandPool(const vk::DeviceInterface & vk,const vk::VkDevice & device,ProtectionMode protectionMode,const deUint32 queueFamilyIdx)573 vk::Move<vk::VkCommandPool> makeCommandPool (const vk::DeviceInterface&	vk,
574 											 const vk::VkDevice&		device,
575 											 ProtectionMode				protectionMode,
576 											 const deUint32				queueFamilyIdx)
577 {
578 	const deUint32	poolFlags	= vk::VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT
579 #ifndef NOT_PROTECTED
580 									| ((protectionMode == PROTECTION_ENABLED) ? vk::VK_COMMAND_POOL_CREATE_PROTECTED_BIT : 0x0)
581 #endif
582 									;
583 #ifdef NOT_PROTECTED
584 	DE_UNREF(protectionMode);
585 #endif
586 
587 	return vk::createCommandPool(vk, device, poolFlags, queueFamilyIdx);
588 }
589 
makeGraphicsPipeline(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineLayout pipelineLayout,const vk::VkRenderPass renderPass,const vk::VkShaderModule vertexShaderModule,const vk::VkShaderModule fragmentShaderModule,const VertexBindings & vertexBindings,const VertexAttribs & vertexAttribs,const tcu::UVec2 & renderSize,const vk::VkPrimitiveTopology topology,const vk::VkPipelineCreateFlags flags)590 vk::Move<vk::VkPipeline> makeGraphicsPipeline (const vk::DeviceInterface&		vk,
591 											   const vk::VkDevice				device,
592 											   const vk::VkPipelineLayout		pipelineLayout,
593 											   const vk::VkRenderPass			renderPass,
594 											   const vk::VkShaderModule			vertexShaderModule,
595 											   const vk::VkShaderModule			fragmentShaderModule,
596 											   const VertexBindings&			vertexBindings,
597 											   const VertexAttribs&				vertexAttribs,
598 											   const tcu::UVec2&				renderSize,
599 											   const vk::VkPrimitiveTopology	topology,
600 											   const vk::VkPipelineCreateFlags	flags)
601 {
602 	const std::vector<VkViewport>				viewports					(1, makeViewport(renderSize));
603 	const std::vector<VkRect2D>					scissors					(1, makeRect2D(renderSize));
604 
605 	const VkPipelineVertexInputStateCreateInfo	vertexInputStateCreateInfo	=
606 	{
607 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,	// VkStructureType                             sType;
608 		DE_NULL,													// const void*                                 pNext;
609 		(VkPipelineVertexInputStateCreateFlags)0,					// VkPipelineVertexInputStateCreateFlags       flags;
610 		(deUint32)vertexBindings.size(),							// deUint32                                    vertexBindingDescriptionCount;
611 		vertexBindings.data(),										// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
612 		(deUint32)vertexAttribs.size(),								// deUint32                                    vertexAttributeDescriptionCount;
613 		vertexAttribs.data()										// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
614 	};
615 
616 	return vk::makeGraphicsPipeline(vk,									// const DeviceInterface&                        vk
617 									device,								// const VkDevice                                device
618 									pipelineLayout,						// const VkPipelineLayout                        pipelineLayout
619 									vertexShaderModule,					// const VkShaderModule                          vertexShaderModule
620 									DE_NULL,							// const VkShaderModule                          tessellationControlModule
621 									DE_NULL,							// const VkShaderModule                          tessellationEvalModule
622 									DE_NULL,							// const VkShaderModule                          geometryShaderModule
623 									fragmentShaderModule,				// const VkShaderModule                          fragmentShaderModule
624 									renderPass,							// const VkRenderPass                            renderPass
625 									viewports,							// const std::vector<VkViewport>&                viewports
626 									scissors,							// const std::vector<VkRect2D>&                  scissors
627 									topology,							// const VkPrimitiveTopology                     topology
628 									0u,									// const deUint32                                subpass
629 									0u,									// const deUint32                                patchControlPoints
630 									&vertexInputStateCreateInfo,		// const VkPipelineVertexInputStateCreateInfo*   vertexInputStateCreateInfo
631 									DE_NULL,							// const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
632 									DE_NULL,							// const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
633 									DE_NULL,							// const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
634 									DE_NULL,							// const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
635 									DE_NULL,							// const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
636 									DE_NULL,							// const void* pNext
637 									flags);
638 }
639 
getCmdBufferTypeStr(const CmdBufferType cmdBufferType)640 const char* getCmdBufferTypeStr (const CmdBufferType cmdBufferType)
641 {
642 	switch (cmdBufferType)
643 	{
644 		case CMD_BUFFER_PRIMARY:	return "primary";
645 		case CMD_BUFFER_SECONDARY:	return "secondary";
646 
647 		default: DE_FATAL("Invalid command buffer type"); return "";
648 	}
649 }
650 
clearImage(ProtectedContext & ctx,vk::VkImage image)651 void clearImage (ProtectedContext& ctx, vk::VkImage image)
652 {
653 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
654 	const vk::VkDevice					device				= ctx.getDevice();
655 	const vk::VkQueue					queue				= ctx.getQueue();
656 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
657 
658 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
659 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
660 
661 	const vk::VkClearColorValue			clearColor			= { { 0.0f, 0.0f, 0.0f, 0.0f } };
662 
663 	const vk::VkImageSubresourceRange	subresourceRange	=
664 	{
665 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
666 		0u,								// uint32_t				baseMipLevel
667 		1u,								// uint32_t				levelCount
668 		0u,								// uint32_t				baseArrayLayer
669 		1u,								// uint32_t				layerCount
670 	};
671 
672 	const vk::VkImageMemoryBarrier		preImageBarrier		=
673 	{
674 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
675 		DE_NULL,										// const void*				pNext;
676 		0u,												// VkAccessFlags			srcAccessMask;
677 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
678 		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
679 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
680 		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
681 		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
682 		image,											// VkImage					image;
683 		subresourceRange								// VkImageSubresourceRange	subresourceRange;
684 	};
685 
686 	const vk::VkImageMemoryBarrier		postImageBarrier	=
687 	{
688 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
689 		DE_NULL,										// const void*				pNext;
690 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
691 		vk::VK_ACCESS_SHADER_WRITE_BIT,					// VkAccessFlags			dstAccessMask;
692 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
693 		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
694 		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
695 		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
696 		image,											// VkImage					image;
697 		subresourceRange								// VkImageSubresourceRange	subresourceRange;
698 	};
699 
700 	beginCommandBuffer(vk, *cmdBuffer);
701 	vk.cmdPipelineBarrier(*cmdBuffer,
702 						  vk::VK_PIPELINE_STAGE_HOST_BIT,
703 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
704 						  (vk::VkDependencyFlags)0,
705 						  0, (const vk::VkMemoryBarrier*)DE_NULL,
706 						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
707 						  1, &preImageBarrier);
708 	vk.cmdClearColorImage(*cmdBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &subresourceRange);
709 	vk.cmdPipelineBarrier(*cmdBuffer,
710 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
711 						  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
712 						  (vk::VkDependencyFlags)0,
713 						  0, (const vk::VkMemoryBarrier*)DE_NULL,
714 						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
715 						  1, &postImageBarrier);
716 	endCommandBuffer(vk, *cmdBuffer);
717 
718 	{
719 		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
720 		VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
721 	}
722 }
723 
uploadImage(ProtectedContext & ctx,vk::VkImage image,const tcu::Texture2D & texture2D)724 void uploadImage (ProtectedContext& ctx, vk::VkImage image, const tcu::Texture2D& texture2D)
725 {
726 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
727 	const vk::VkDevice					device				= ctx.getDevice();
728 	const vk::VkQueue					queue				= ctx.getQueue();
729 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
730 
731 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_DISABLED, queueFamilyIndex));
732 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
733 
734 	const deUint32						width				= (deUint32)texture2D.getWidth();
735 	const deUint32						height				= (deUint32)texture2D.getHeight();
736 	const deUint32						stagingBufferSize	= width * height * tcu::getPixelSize(texture2D.getFormat());
737 
738 	de::UniquePtr<vk::BufferWithMemory>	stagingBuffer		(makeBuffer(ctx,
739 																		PROTECTION_DISABLED,
740 																		queueFamilyIndex,
741 																		stagingBufferSize,
742 																		vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
743 																		vk::MemoryRequirement::HostVisible));
744 
745 	{
746 		const tcu::ConstPixelBufferAccess&	access		= texture2D.getLevel(0);
747 		const tcu::PixelBufferAccess		destAccess	(access.getFormat(), access.getSize(), stagingBuffer->getAllocation().getHostPtr());
748 
749 		tcu::copy(destAccess, access);
750 
751 		flushAlloc(vk, device, stagingBuffer->getAllocation());
752 	}
753 
754 	const vk::VkImageSubresourceRange	subresourceRange	=
755 	{
756 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
757 		0u,								// uint32_t				baseMipLevel
758 		1u,								// uint32_t				levelCount
759 		0u,								// uint32_t				baseArrayLayer
760 		1u,								// uint32_t				layerCount
761 	};
762 
763 	const vk::VkImageMemoryBarrier		preCopyBarrier		=
764 	{
765 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
766 		DE_NULL,										// const void*				pNext;
767 		0u,												// VkAccessFlags			srcAccessMask;
768 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
769 		vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
770 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			newLayout;
771 		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
772 		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
773 		image,											// VkImage					image;
774 		subresourceRange								// VkImageSubresourceRange	subresourceRange;
775 	};
776 
777 	const vk::VkImageMemoryBarrier		postCopyBarrier		=
778 	{
779 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
780 		DE_NULL,										// const void*				pNext;
781 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
782 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
783 		vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,		// VkImageLayout			oldLayout;
784 		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
785 		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
786 		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
787 		image,											// VkImage					image;
788 		subresourceRange								// VkImageSubresourceRange	subresourceRange;
789 	};
790 
791 	const vk::VkImageSubresourceLayers	subresourceLayers	=
792 	{
793 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
794 		0u,								// deUint32				mipLevel;
795 		0u,								// deUint32				baseArrayLayer;
796 		1u								// deUint32				layerCount;
797 	};
798 
799 	const vk::VkBufferImageCopy			copyRegion			=
800 	{
801 		0u,								// VkDeviceSize					bufferOffset;
802 		width,							// deUint32						bufferRowLength;
803 		height,							// deUint32						bufferImageHeight;
804 		subresourceLayers,				// VkImageSubresourceLayers		imageSubresource;
805 		{ 0u, 0u, 0u },					// VkOffset3D					imageOffset;
806 		{ width, height, 1u }			// VkExtent3D					imageExtent;
807 	};
808 
809 	beginCommandBuffer(vk, *cmdBuffer);
810 	vk.cmdPipelineBarrier(*cmdBuffer,
811 						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_HOST_BIT,
812 						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
813 						  (vk::VkDependencyFlags)0u,
814 						  0u, (const vk::VkMemoryBarrier*)DE_NULL,
815 						  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
816 						  1u, &preCopyBarrier);
817 	vk.cmdCopyBufferToImage(*cmdBuffer, **stagingBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &copyRegion);
818 	vk.cmdPipelineBarrier(*cmdBuffer,
819 						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
820 						  (vk::VkPipelineStageFlags)vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
821 						  (vk::VkDependencyFlags)0u,
822 						  0u, (const vk::VkMemoryBarrier*)DE_NULL,
823 						  0u, (const vk::VkBufferMemoryBarrier*)DE_NULL,
824 						  1u, &postCopyBarrier);
825 	endCommandBuffer(vk, *cmdBuffer);
826 
827 	{
828 		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
829 		VK_CHECK(queueSubmit(ctx, PROTECTION_DISABLED, queue, *cmdBuffer, *fence, ~0ull));
830 	}
831 }
832 
copyToProtectedImage(ProtectedContext & ctx,vk::VkImage srcImage,vk::VkImage dstImage,vk::VkImageLayout dstImageLayout,deUint32 width,deUint32 height,ProtectionMode protectionMode)833 void copyToProtectedImage (ProtectedContext& ctx, vk::VkImage srcImage, vk::VkImage dstImage, vk::VkImageLayout dstImageLayout, deUint32 width, deUint32 height, ProtectionMode protectionMode)
834 {
835 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
836 	const vk::VkDevice					device				= ctx.getDevice();
837 	const vk::VkQueue					queue				= ctx.getQueue();
838 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
839 
840 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, protectionMode, queueFamilyIndex));
841 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
842 
843 	const vk::VkImageSubresourceRange	subresourceRange	=
844 	{
845 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
846 		0u,								// uint32_t				baseMipLevel
847 		1u,								// uint32_t				levelCount
848 		0u,								// uint32_t				baseArrayLayer
849 		1u,								// uint32_t				layerCount
850 	};
851 
852 	const vk::VkImageMemoryBarrier		preImageBarriers[]	=
853 	{
854 		// source image
855 		{
856 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
857 			DE_NULL,										// const void*				pNext;
858 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
859 			vk::VK_ACCESS_TRANSFER_READ_BIT,				// VkAccessFlags			dstAccessMask;
860 			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			oldLayout;
861 			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
862 			queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
863 			queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
864 			srcImage,										// VkImage					image;
865 			subresourceRange								// VkImageSubresourceRange	subresourceRange;
866 		},
867 		// destination image
868 		{
869 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
870 			DE_NULL,										// const void*				pNext;
871 			0,												// VkAccessFlags			srcAccessMask;
872 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			dstAccessMask;
873 			vk::VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout			oldLayout;
874 			vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			newLayout;
875 			queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
876 			queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
877 			dstImage,										// VkImage					image;
878 			subresourceRange								// VkImageSubresourceRange	subresourceRange;
879 		}
880 	};
881 
882 	const vk::VkImageMemoryBarrier		postImgBarrier		=
883 	{
884 		vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,		// VkStructureType			sType;
885 		DE_NULL,										// const void*				pNext;
886 		vk::VK_ACCESS_TRANSFER_WRITE_BIT,				// VkAccessFlags			srcAccessMask;
887 		vk::VK_ACCESS_SHADER_READ_BIT,					// VkAccessFlags			dstAccessMask;
888 		vk::VK_IMAGE_LAYOUT_GENERAL,					// VkImageLayout			oldLayout;
889 		dstImageLayout,									// VkImageLayout			newLayout;
890 		queueFamilyIndex,								// deUint32					srcQueueFamilyIndex;
891 		queueFamilyIndex,								// deUint32					dstQueueFamilyIndex;
892 		dstImage,										// VkImage					image;
893 		subresourceRange								// VkImageSubresourceRange	subresourceRange;
894 	};
895 
896 	const vk::VkImageSubresourceLayers	subresourceLayers	=
897 	{
898 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask;
899 		0u,								// deUint32				mipLevel;
900 		0u,								// deUint32				baseArrayLayer;
901 		1u								// deUint32				layerCount;
902 	};
903 
904 	const vk::VkImageCopy				copyImageRegion		=
905 	{
906 		subresourceLayers,		// VkImageSubresourceCopy	srcSubresource;
907 		{ 0, 0, 0 },			// VkOffset3D				srcOffset;
908 		subresourceLayers,		// VkImageSubresourceCopy	destSubresource;
909 		{ 0, 0, 0 },			// VkOffset3D				destOffset;
910 		{ width, height, 1u },	// VkExtent3D				extent;
911 	};
912 
913 	beginCommandBuffer(vk, *cmdBuffer);
914 	vk.cmdPipelineBarrier(*cmdBuffer,
915 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
916 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
917 						  (vk::VkDependencyFlags)0,
918 						  0, (const vk::VkMemoryBarrier*)DE_NULL,
919 						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
920 						  DE_LENGTH_OF_ARRAY(preImageBarriers), preImageBarriers);
921 	vk.cmdCopyImage(*cmdBuffer, srcImage, vk::VK_IMAGE_LAYOUT_GENERAL, dstImage, vk::VK_IMAGE_LAYOUT_GENERAL, 1u, &copyImageRegion);
922 	vk.cmdPipelineBarrier(*cmdBuffer,
923 						  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
924 						  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
925 						  (vk::VkDependencyFlags)0,
926 						  0, (const vk::VkMemoryBarrier*)DE_NULL,
927 						  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
928 						  1, &postImgBarrier);
929 	endCommandBuffer(vk, *cmdBuffer);
930 
931 	{
932 		const vk::Unique<vk::VkFence>	fence		(createFence(vk, device));
933 		VK_CHECK(queueSubmit(ctx, protectionMode, queue, *cmdBuffer, *fence, ~0ull));
934 	}
935 }
936 
fillWithRandomColorTiles(const tcu::PixelBufferAccess & dst,const tcu::Vec4 & minVal,const tcu::Vec4 & maxVal,deUint32 seed)937 void fillWithRandomColorTiles (const tcu::PixelBufferAccess& dst, const tcu::Vec4& minVal, const tcu::Vec4& maxVal, deUint32 seed)
938 {
939 	const int	numCols		= dst.getWidth()  >= 7 ? 7 : dst.getWidth();
940 	const int	numRows		= dst.getHeight() >= 5 ? 5 : dst.getHeight();
941 	de::Random	rnd			(seed);
942 
943 	for (int slice = 0; slice < dst.getDepth(); slice++)
944 	for (int row = 0; row < numRows; row++)
945 	for (int col = 0; col < numCols; col++)
946 	{
947 		const int	yBegin	= (row + 0)*dst.getHeight() / numRows;
948 		const int	yEnd	= (row + 1)*dst.getHeight() / numRows;
949 		const int	xBegin	= (col + 0)*dst.getWidth() / numCols;
950 		const int	xEnd	= (col + 1)*dst.getWidth() / numCols;
951 		tcu::Vec4	color;
952 		for (int i = 0; i < 4; i++)
953 			color[i] = rnd.getFloat(minVal[i], maxVal[i]);
954 		tcu::clear(tcu::getSubregion(dst, xBegin, yBegin, slice, xEnd - xBegin, yEnd - yBegin, 1), color);
955 	}
956 }
957 
fillWithUniqueColors(const tcu::PixelBufferAccess & dst,deUint32 seed)958 void fillWithUniqueColors (const tcu::PixelBufferAccess& dst, deUint32 seed)
959 {
960 	// This is an implementation of linear congruential generator.
961 	// The A and M are prime numbers, thus allowing to generate unique number sequence of length genM-1.
962 	// The generator uses C constant as 0, thus value of 0 is not allowed as a seed.
963 	const deUint64	genA	= 1573051ull;
964 	const deUint64	genM	= 2097023ull;
965 	deUint64		genX	= seed % genM;
966 
967 	DE_ASSERT(deUint64(dst.getWidth()) * deUint64(dst.getHeight()) * deUint64(dst.getDepth()) < genM - 1);
968 
969 	if (genX == 0)
970 		genX = 1;
971 
972 	const int	numCols		= dst.getWidth();
973 	const int	numRows		= dst.getHeight();
974 	const int	numSlices	= dst.getDepth();
975 
976 	for (int z = 0; z < numSlices; z++)
977 	for (int y = 0; y < numRows; y++)
978 	for (int x = 0; x < numCols; x++)
979 	{
980 		genX = (genA * genX) % genM;
981 
982 		DE_ASSERT(genX != seed);
983 
984 		const float		r		= float(deUint32((genX >> 0)  & 0x7F)) / 127.0f;
985 		const float		g		= float(deUint32((genX >> 7)  & 0x7F)) / 127.0f;
986 		const float		b		= float(deUint32((genX >> 14) & 0x7F)) / 127.0f;
987 		const tcu::Vec4	color	= tcu::Vec4(r, g, b, 1.0f);
988 
989 		dst.setPixel(color, x, y, z);
990 	}
991 }
992 
993 } // ProtectedMem
994 } // vkt
995