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