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