• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Synchronization tests utilities
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "vkBarrierUtil.hpp"
28 #include "deStringUtil.hpp"
29 #include <set>
30 #include <limits>
31 
32 namespace vkt
33 {
34 namespace synchronization
35 {
36 using namespace vk;
37 
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)38 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
39 {
40 	const VkCommandBufferAllocateInfo info =
41 	{
42 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,		// VkStructureType		sType;
43 		DE_NULL,											// const void*			pNext;
44 		commandPool,										// VkCommandPool		commandPool;
45 		VK_COMMAND_BUFFER_LEVEL_PRIMARY,					// VkCommandBufferLevel	level;
46 		1u,													// deUint32				commandBufferCount;
47 	};
48 	return allocateCommandBuffer(vk, device, &info);
49 }
50 
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo,PipelineCacheData & pipelineCacheData)51 Move<VkPipeline> makeComputePipeline (const DeviceInterface&		vk,
52 									  const VkDevice				device,
53 									  const VkPipelineLayout		pipelineLayout,
54 									  const VkShaderModule			shaderModule,
55 									  const VkSpecializationInfo*	specInfo,
56 									  PipelineCacheData&			pipelineCacheData)
57 {
58 	const VkPipelineShaderStageCreateInfo shaderStageInfo =
59 	{
60 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType					sType;
61 		DE_NULL,												// const void*						pNext;
62 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags	flags;
63 		VK_SHADER_STAGE_COMPUTE_BIT,							// VkShaderStageFlagBits			stage;
64 		shaderModule,											// VkShaderModule					module;
65 		"main",													// const char*						pName;
66 		specInfo,												// const VkSpecializationInfo*		pSpecializationInfo;
67 	};
68 	const VkComputePipelineCreateInfo pipelineInfo =
69 	{
70 		VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,		// VkStructureType					sType;
71 		DE_NULL,											// const void*						pNext;
72 		(VkPipelineCreateFlags)0,							// VkPipelineCreateFlags			flags;
73 		shaderStageInfo,									// VkPipelineShaderStageCreateInfo	stage;
74 		pipelineLayout,										// VkPipelineLayout					layout;
75 		DE_NULL,											// VkPipeline						basePipelineHandle;
76 		0,													// deInt32							basePipelineIndex;
77 	};
78 
79 	{
80 		const vk::Unique<vk::VkPipelineCache>	pipelineCache	(pipelineCacheData.createPipelineCache(vk, device));
81 		vk::Move<vk::VkPipeline>				pipeline		(createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
82 
83 		// Refresh data from cache
84 		pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
85 
86 		return pipeline;
87 	}
88 }
89 
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage,const VkSampleCountFlagBits samples)90 VkImageCreateInfo makeImageCreateInfo (const VkImageType			imageType,
91 									   const VkExtent3D&			extent,
92 									   const VkFormat				format,
93 									   const VkImageUsageFlags		usage,
94 									   const VkSampleCountFlagBits	samples)
95 {
96 	return
97 	{
98 		VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,		// VkStructureType          sType;
99 		DE_NULL,									// const void*              pNext;
100 		(VkImageCreateFlags)0,						// VkImageCreateFlags       flags;
101 		imageType,									// VkImageType              imageType;
102 		format,										// VkFormat                 format;
103 		extent,										// VkExtent3D               extent;
104 		1u,											// uint32_t                 mipLevels;
105 		1u,											// uint32_t                 arrayLayers;
106 		samples,									// VkSampleCountFlagBits    samples;
107 		VK_IMAGE_TILING_OPTIMAL,					// VkImageTiling            tiling;
108 		usage,										// VkImageUsageFlags        usage;
109 		VK_SHARING_MODE_EXCLUSIVE,					// VkSharingMode            sharingMode;
110 		0u,											// uint32_t                 queueFamilyIndexCount;
111 		DE_NULL,									// const uint32_t*          pQueueFamilyIndices;
112 		VK_IMAGE_LAYOUT_UNDEFINED,					// VkImageLayout            initialLayout;
113 	};
114 }
115 
beginRenderPassWithRasterizationDisabled(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer)116 void beginRenderPassWithRasterizationDisabled (const DeviceInterface&	vk,
117 											   const VkCommandBuffer	commandBuffer,
118 											   const VkRenderPass		renderPass,
119 											   const VkFramebuffer		framebuffer)
120 {
121 	const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
122 
123 	beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
124 }
125 
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)126 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&			vk,
127 															 const VkDevice					device,
128 															 const VkShaderStageFlagBits	stage,
129 															 const ProgramBinary&			binary,
130 															 const VkSpecializationInfo*	specInfo)
131 {
132 	VkShaderModule module;
133 	switch (stage)
134 	{
135 		case (VK_SHADER_STAGE_VERTEX_BIT):
136 			DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
137 			m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
138 			module = *m_vertexShaderModule;
139 			break;
140 
141 		case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
142 			DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
143 			m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
144 			module = *m_tessControlShaderModule;
145 			break;
146 
147 		case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
148 			DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
149 			m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
150 			module = *m_tessEvaluationShaderModule;
151 			break;
152 
153 		case (VK_SHADER_STAGE_GEOMETRY_BIT):
154 			DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
155 			m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
156 			module = *m_geometryShaderModule;
157 			break;
158 
159 		case (VK_SHADER_STAGE_FRAGMENT_BIT):
160 			DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
161 			m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
162 			module = *m_fragmentShaderModule;
163 			break;
164 
165 		default:
166 			DE_FATAL("Invalid shader stage");
167 			return *this;
168 	}
169 
170 	const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
171 	{
172 		VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,	// VkStructureType						sType;
173 		DE_NULL,												// const void*							pNext;
174 		(VkPipelineShaderStageCreateFlags)0,					// VkPipelineShaderStageCreateFlags		flags;
175 		stage,													// VkShaderStageFlagBits				stage;
176 		module,													// VkShaderModule						module;
177 		"main",													// const char*							pName;
178 		specInfo,												// const VkSpecializationInfo*			pSpecializationInfo;
179 	};
180 
181 	m_shaderStageFlags |= stage;
182 	m_shaderStages.push_back(pipelineShaderStageInfo);
183 
184 	return *this;
185 }
186 
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)187 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
188 {
189 	const VkVertexInputBindingDescription bindingDesc =
190 	{
191 		0u,									// uint32_t				binding;
192 		stride,								// uint32_t				stride;
193 		VK_VERTEX_INPUT_RATE_VERTEX,		// VkVertexInputRate	inputRate;
194 	};
195 	const VkVertexInputAttributeDescription attributeDesc =
196 	{
197 		0u,									// uint32_t			location;
198 		0u,									// uint32_t			binding;
199 		vertexFormat,						// VkFormat			format;
200 		0u,									// uint32_t			offset;
201 	};
202 
203 	m_vertexInputBindings.clear();
204 	m_vertexInputBindings.push_back(bindingDesc);
205 
206 	m_vertexInputAttributes.clear();
207 	m_vertexInputAttributes.push_back(attributeDesc);
208 
209 	return *this;
210 }
211 
212 template<typename T>
dataPointer(const std::vector<T> & vec)213 inline const T* dataPointer (const std::vector<T>& vec)
214 {
215 	return (vec.size() != 0 ? &vec[0] : DE_NULL);
216 }
217 
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,PipelineCacheData & pipelineCacheData)218 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&	vk,
219 												 const VkDevice			device,
220 												 const VkPipelineLayout	pipelineLayout,
221 												 const VkRenderPass		renderPass,
222 												 PipelineCacheData&		pipelineCacheData)
223 {
224 	const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
225 	{
226 		VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,		// VkStructureType                             sType;
227 		DE_NULL,														// const void*                                 pNext;
228 		(VkPipelineVertexInputStateCreateFlags)0,						// VkPipelineVertexInputStateCreateFlags       flags;
229 		static_cast<deUint32>(m_vertexInputBindings.size()),			// uint32_t                                    vertexBindingDescriptionCount;
230 		dataPointer(m_vertexInputBindings),								// const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
231 		static_cast<deUint32>(m_vertexInputAttributes.size()),			// uint32_t                                    vertexAttributeDescriptionCount;
232 		dataPointer(m_vertexInputAttributes),							// const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
233 	};
234 
235 	const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
236 																										 : m_primitiveTopology;
237 	const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
238 	{
239 		VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,	// VkStructureType                             sType;
240 		DE_NULL,														// const void*                                 pNext;
241 		(VkPipelineInputAssemblyStateCreateFlags)0,						// VkPipelineInputAssemblyStateCreateFlags     flags;
242 		topology,														// VkPrimitiveTopology                         topology;
243 		VK_FALSE,														// VkBool32                                    primitiveRestartEnable;
244 	};
245 
246 	const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
247 	{
248 		VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,		// VkStructureType                             sType;
249 		DE_NULL,														// const void*                                 pNext;
250 		(VkPipelineTessellationStateCreateFlags)0,						// VkPipelineTessellationStateCreateFlags      flags;
251 		m_patchControlPoints,											// uint32_t                                    patchControlPoints;
252 	};
253 
254 	const VkViewport	viewport	= makeViewport(m_renderSize);
255 	const VkRect2D		scissor		= makeRect2D(m_renderSize);
256 
257 	const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
258 	{
259 		VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,	// VkStructureType                             sType;
260 		DE_NULL,												// const void*                                 pNext;
261 		(VkPipelineViewportStateCreateFlags)0,					// VkPipelineViewportStateCreateFlags          flags;
262 		1u,														// uint32_t                                    viewportCount;
263 		&viewport,												// const VkViewport*                           pViewports;
264 		1u,														// uint32_t                                    scissorCount;
265 		&scissor,												// const VkRect2D*                             pScissors;
266 	};
267 
268 	const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
269 	const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
270 	{
271 		VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,		// VkStructureType                          sType;
272 		DE_NULL,														// const void*                              pNext;
273 		(VkPipelineRasterizationStateCreateFlags)0,						// VkPipelineRasterizationStateCreateFlags  flags;
274 		VK_FALSE,														// VkBool32                                 depthClampEnable;
275 		isRasterizationDisabled,										// VkBool32                                 rasterizerDiscardEnable;
276 		VK_POLYGON_MODE_FILL,											// VkPolygonMode							polygonMode;
277 		m_cullModeFlags,												// VkCullModeFlags							cullMode;
278 		m_frontFace,													// VkFrontFace								frontFace;
279 		VK_FALSE,														// VkBool32									depthBiasEnable;
280 		0.0f,															// float									depthBiasConstantFactor;
281 		0.0f,															// float									depthBiasClamp;
282 		0.0f,															// float									depthBiasSlopeFactor;
283 		1.0f,															// float									lineWidth;
284 	};
285 
286 	const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
287 	{
288 		VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,	// VkStructureType							sType;
289 		DE_NULL,													// const void*								pNext;
290 		(VkPipelineMultisampleStateCreateFlags)0,					// VkPipelineMultisampleStateCreateFlags	flags;
291 		VK_SAMPLE_COUNT_1_BIT,										// VkSampleCountFlagBits					rasterizationSamples;
292 		VK_FALSE,													// VkBool32									sampleShadingEnable;
293 		0.0f,														// float									minSampleShading;
294 		DE_NULL,													// const VkSampleMask*						pSampleMask;
295 		VK_FALSE,													// VkBool32									alphaToCoverageEnable;
296 		VK_FALSE													// VkBool32									alphaToOneEnable;
297 	};
298 
299 	const VkStencilOpState stencilOpState = makeStencilOpState(
300 		VK_STENCIL_OP_KEEP,		// stencil fail
301 		VK_STENCIL_OP_KEEP,		// depth & stencil pass
302 		VK_STENCIL_OP_KEEP,		// depth only fail
303 		VK_COMPARE_OP_NEVER,	// compare op
304 		0u,						// compare mask
305 		0u,						// write mask
306 		0u);					// reference
307 
308 	const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
309 	{
310 		VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,	// VkStructureType							sType;
311 		DE_NULL,													// const void*								pNext;
312 		(VkPipelineDepthStencilStateCreateFlags)0,					// VkPipelineDepthStencilStateCreateFlags	flags;
313 		VK_FALSE,													// VkBool32									depthTestEnable;
314 		VK_FALSE,													// VkBool32									depthWriteEnable;
315 		VK_COMPARE_OP_LESS,											// VkCompareOp								depthCompareOp;
316 		VK_FALSE,													// VkBool32									depthBoundsTestEnable;
317 		VK_FALSE,													// VkBool32									stencilTestEnable;
318 		stencilOpState,												// VkStencilOpState							front;
319 		stencilOpState,												// VkStencilOpState							back;
320 		0.0f,														// float									minDepthBounds;
321 		1.0f,														// float									maxDepthBounds;
322 	};
323 
324 	const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
325 	const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
326 	{
327 		m_blendEnable,						// VkBool32					blendEnable;
328 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcColorBlendFactor;
329 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstColorBlendFactor;
330 		VK_BLEND_OP_ADD,					// VkBlendOp				colorBlendOp;
331 		VK_BLEND_FACTOR_SRC_ALPHA,			// VkBlendFactor			srcAlphaBlendFactor;
332 		VK_BLEND_FACTOR_ONE,				// VkBlendFactor			dstAlphaBlendFactor;
333 		VK_BLEND_OP_ADD,					// VkBlendOp				alphaBlendOp;
334 		colorComponentsAll,					// VkColorComponentFlags	colorWriteMask;
335 	};
336 
337 	const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
338 	{
339 		VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,	// VkStructureType								sType;
340 		DE_NULL,													// const void*									pNext;
341 		(VkPipelineColorBlendStateCreateFlags)0,					// VkPipelineColorBlendStateCreateFlags			flags;
342 		VK_FALSE,													// VkBool32										logicOpEnable;
343 		VK_LOGIC_OP_COPY,											// VkLogicOp									logicOp;
344 		1u,															// deUint32										attachmentCount;
345 		&pipelineColorBlendAttachmentState,							// const VkPipelineColorBlendAttachmentState*	pAttachments;
346 		{ 0.0f, 0.0f, 0.0f, 0.0f },									// float										blendConstants[4];
347 	};
348 
349 	const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
350 	{
351 		VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,						// VkStructureType									sType;
352 		DE_NULL,																// const void*										pNext;
353 		(VkPipelineCreateFlags)0,												// VkPipelineCreateFlags							flags;
354 		static_cast<deUint32>(m_shaderStages.size()),							// deUint32											stageCount;
355 		&m_shaderStages[0],														// const VkPipelineShaderStageCreateInfo*			pStages;
356 		&vertexInputStateInfo,													// const VkPipelineVertexInputStateCreateInfo*		pVertexInputState;
357 		&pipelineInputAssemblyStateInfo,										// const VkPipelineInputAssemblyStateCreateInfo*	pInputAssemblyState;
358 		(m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*		pTessellationState;
359 		(isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),		// const VkPipelineViewportStateCreateInfo*			pViewportState;
360 		&pipelineRasterizationStateInfo,										// const VkPipelineRasterizationStateCreateInfo*	pRasterizationState;
361 		(isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),	// const VkPipelineMultisampleStateCreateInfo*		pMultisampleState;
362 		(isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),	// const VkPipelineDepthStencilStateCreateInfo*		pDepthStencilState;
363 		(isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),		// const VkPipelineColorBlendStateCreateInfo*		pColorBlendState;
364 		DE_NULL,																// const VkPipelineDynamicStateCreateInfo*			pDynamicState;
365 		pipelineLayout,															// VkPipelineLayout									layout;
366 		renderPass,																// VkRenderPass										renderPass;
367 		0u,																		// deUint32											subpass;
368 		DE_NULL,																// VkPipeline										basePipelineHandle;
369 		0,																		// deInt32											basePipelineIndex;
370 	};
371 
372 	{
373 		const vk::Unique<vk::VkPipelineCache>	pipelineCache	(pipelineCacheData.createPipelineCache(vk, device));
374 		vk::Move<vk::VkPipeline>				pipeline		(createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
375 
376 		// Refresh data from cache
377 		pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
378 
379 		return pipeline;
380 	}
381 }
382 
383 // Uses some structures added by VK_KHR_synchronization2 to fill legacy structures.
384 // With this approach we dont have to create branch in each test (one for legacy
385 // second for new synchronization), this helps to reduce code of some tests.
386 class LegacySynchronizationWrapper : public SynchronizationWrapperBase
387 {
388 protected:
389 
390 	struct SubmitInfoData
391 	{
392 		deUint32		waitSemaphoreCount;
393 		std::size_t		waitSemaphoreIndex;
394 		std::size_t		waitSemaphoreValueIndexPlusOne;
395 		deUint32		commandBufferCount;
396 		deUint32		commandBufferIndex;
397 		deUint32		signalSemaphoreCount;
398 		std::size_t		signalSemaphoreIndex;
399 		std::size_t		signalSemaphoreValueIndexPlusOne;
400 	};
401 
isStageFlagAllowed(VkPipelineStageFlags2KHR stage) const402 	bool isStageFlagAllowed(VkPipelineStageFlags2KHR stage) const
403 	{
404 		// synchronization2 suports more stages then legacy synchronization
405 		// and so SynchronizationWrapper can only be used for cases that
406 		// operate on stages also supported by legacy synchronization
407 		// NOTE: if some tests hits assertion that uses this method then this
408 		// test should not use synchronizationWrapper - it should be synchronization2 exclusive
409 
410 		static const std::set<deUint32> allowedStages
411 		{
412 			VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
413 			VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
414 			VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
415 			VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
416 			VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
417 			VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
418 			VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
419 			VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
420 			VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
421 			VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
422 			VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
423 			VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
424 			VK_PIPELINE_STAGE_TRANSFER_BIT,
425 			VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
426 			VK_PIPELINE_STAGE_HOST_BIT,
427 			VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
428 			VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
429 			VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
430 			VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT,
431 			VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
432 			VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
433 			VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV,
434 			VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
435 			VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
436 			VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,
437 			VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV,
438 			VK_PIPELINE_STAGE_NONE_KHR,
439 		};
440 
441 		if (stage > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
442 			return false;
443 
444 		return (allowedStages.find(static_cast<deUint32>(stage)) != allowedStages.end());
445 	}
446 
isAccessFlagAllowed(VkAccessFlags2KHR access) const447 	bool isAccessFlagAllowed(VkAccessFlags2KHR access) const
448 	{
449 		// synchronization2 suports more access flags then legacy synchronization
450 		// and so SynchronizationWrapper can only be used for cases that
451 		// operate on access flags also supported by legacy synchronization
452 		// NOTE: if some tests hits assertion that uses this method then this
453 		// test should not use synchronizationWrapper - it should be synchronization2 exclusive
454 
455 		static const std::set<deUint32> allowedAccessFlags
456 		{
457 			VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
458 			VK_ACCESS_INDEX_READ_BIT,
459 			VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
460 			VK_ACCESS_UNIFORM_READ_BIT,
461 			VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
462 			VK_ACCESS_SHADER_READ_BIT,
463 			VK_ACCESS_SHADER_WRITE_BIT,
464 			VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
465 			VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
466 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
467 			VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
468 			VK_ACCESS_TRANSFER_READ_BIT,
469 			VK_ACCESS_TRANSFER_WRITE_BIT,
470 			VK_ACCESS_HOST_READ_BIT,
471 			VK_ACCESS_HOST_WRITE_BIT,
472 			VK_ACCESS_MEMORY_READ_BIT,
473 			VK_ACCESS_MEMORY_WRITE_BIT,
474 			VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
475 			VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
476 			VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
477 			VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
478 			VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT,
479 			VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
480 			VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
481 			VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV ,
482 			VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,
483 			VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV,
484 			VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV,
485 			VK_ACCESS_NONE_KHR,
486 		};
487 
488 		if (access > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
489 			return false;
490 
491 		return (allowedAccessFlags.find(static_cast<deUint32>(access)) != allowedAccessFlags.end());
492 	}
493 
494 public:
LegacySynchronizationWrapper(const DeviceInterface & vk,bool usingTimelineSemaphores,deUint32 submitInfoCount=1u)495 	LegacySynchronizationWrapper(const DeviceInterface& vk, bool usingTimelineSemaphores, deUint32 submitInfoCount = 1u)
496 		: SynchronizationWrapperBase	(vk)
497 		, m_submited					(DE_FALSE)
498 	{
499 		m_waitSemaphores.reserve(submitInfoCount);
500 		m_signalSemaphores.reserve(submitInfoCount);
501 		m_waitDstStageMasks.reserve(submitInfoCount);
502 		m_commandBuffers.reserve(submitInfoCount);
503 		m_submitInfoData.reserve(submitInfoCount);
504 
505 		if (usingTimelineSemaphores)
506 			m_timelineSemaphoreValues.reserve(2 * submitInfoCount);
507 	}
508 
509 	~LegacySynchronizationWrapper() = default;
510 
addSubmitInfo(deUint32 waitSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pWaitSemaphoreInfos,deUint32 commandBufferInfoCount,const VkCommandBufferSubmitInfoKHR * pCommandBufferInfos,deUint32 signalSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pSignalSemaphoreInfos,bool usingWaitTimelineSemaphore,bool usingSignalTimelineSemaphore)511 	void addSubmitInfo(deUint32								waitSemaphoreInfoCount,
512 					   const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos,
513 					   deUint32								commandBufferInfoCount,
514 					   const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos,
515 					   deUint32								signalSemaphoreInfoCount,
516 					   const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos,
517 					   bool									usingWaitTimelineSemaphore,
518 					   bool									usingSignalTimelineSemaphore) override
519 	{
520 		m_submitInfoData.push_back(SubmitInfoData{ waitSemaphoreInfoCount, 0, 0, commandBufferInfoCount, 0u, signalSemaphoreInfoCount, 0, 0 });
521 		SubmitInfoData& si = m_submitInfoData.back();
522 
523 		// memorize wait values
524 		if (usingWaitTimelineSemaphore)
525 		{
526 			DE_ASSERT(pWaitSemaphoreInfos);
527 			si.waitSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
528 			for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
529 				m_timelineSemaphoreValues.push_back(pWaitSemaphoreInfos[i].value);
530 		}
531 
532 		// memorize signal values
533 		if (usingSignalTimelineSemaphore)
534 		{
535 			DE_ASSERT(pSignalSemaphoreInfos);
536 			si.signalSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
537 			for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
538 				m_timelineSemaphoreValues.push_back(pSignalSemaphoreInfos[i].value);
539 		}
540 
541 		// construct list of semaphores that we need to wait on
542 		if (waitSemaphoreInfoCount)
543 		{
544 			si.waitSemaphoreIndex = m_waitSemaphores.size();
545 			for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
546 			{
547 				DE_ASSERT(isStageFlagAllowed(pWaitSemaphoreInfos[i].stageMask));
548 				m_waitSemaphores.push_back(pWaitSemaphoreInfos[i].semaphore);
549 				m_waitDstStageMasks.push_back(static_cast<VkPipelineStageFlags>(pWaitSemaphoreInfos[i].stageMask));
550 			}
551 		}
552 
553 		// construct list of command buffers
554 		if (commandBufferInfoCount)
555 		{
556 			si.commandBufferIndex = static_cast<deUint32>(m_commandBuffers.size());
557 			for (deUint32 i = 0; i < commandBufferInfoCount; ++i)
558 				m_commandBuffers.push_back(pCommandBufferInfos[i].commandBuffer);
559 		}
560 
561 		// construct list of semaphores that will be signaled
562 		if (signalSemaphoreInfoCount)
563 		{
564 			si.signalSemaphoreIndex = m_signalSemaphores.size();
565 			for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
566 				m_signalSemaphores.push_back(pSignalSemaphoreInfos[i].semaphore);
567 		}
568 	}
569 
cmdPipelineBarrier(VkCommandBuffer commandBuffer,const VkDependencyInfoKHR * pDependencyInfo) const570 	void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
571 	{
572 		DE_ASSERT(pDependencyInfo);
573 
574 		VkPipelineStageFlags	srcStageMask				= VK_PIPELINE_STAGE_NONE_KHR;
575 		VkPipelineStageFlags	dstStageMask				= VK_PIPELINE_STAGE_NONE_KHR;
576 		deUint32				memoryBarrierCount			= pDependencyInfo->memoryBarrierCount;
577 		VkMemoryBarrier*		pMemoryBarriers				= DE_NULL;
578 		deUint32				bufferMemoryBarrierCount	= pDependencyInfo->bufferMemoryBarrierCount;
579 		VkBufferMemoryBarrier*	pBufferMemoryBarriers		= DE_NULL;
580 		deUint32				imageMemoryBarrierCount		= pDependencyInfo->imageMemoryBarrierCount;
581 		VkImageMemoryBarrier*	pImageMemoryBarriers		= DE_NULL;
582 
583 		// translate VkMemoryBarrier2KHR to VkMemoryBarrier
584 		std::vector<VkMemoryBarrier> memoryBarriers;
585 		if (memoryBarrierCount)
586 		{
587 			memoryBarriers.reserve(memoryBarrierCount);
588 			for (deUint32 i = 0; i < memoryBarrierCount; ++i)
589 			{
590 				const VkMemoryBarrier2KHR& pMemoryBarrier = pDependencyInfo->pMemoryBarriers[i];
591 
592 				DE_ASSERT(isStageFlagAllowed(pMemoryBarrier.srcStageMask));
593 				DE_ASSERT(isStageFlagAllowed(pMemoryBarrier.dstStageMask));
594 				DE_ASSERT(isAccessFlagAllowed(pMemoryBarrier.srcAccessMask));
595 				DE_ASSERT(isAccessFlagAllowed(pMemoryBarrier.dstAccessMask));
596 
597 				srcStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.srcStageMask);
598 				dstStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.dstStageMask);
599 				memoryBarriers.push_back(makeMemoryBarrier(
600 					static_cast<VkAccessFlags>(pMemoryBarrier.srcAccessMask),
601 					static_cast<VkAccessFlags>(pMemoryBarrier.dstAccessMask)
602 				));
603 			}
604 			pMemoryBarriers = &memoryBarriers[0];
605 		}
606 
607 		// translate VkBufferMemoryBarrier2KHR to VkBufferMemoryBarrier
608 		std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers;
609 		if (bufferMemoryBarrierCount)
610 		{
611 			bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
612 			for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
613 			{
614 				const VkBufferMemoryBarrier2KHR& pBufferMemoryBarrier = pDependencyInfo->pBufferMemoryBarriers[i];
615 
616 				DE_ASSERT(isStageFlagAllowed(pBufferMemoryBarrier.srcStageMask));
617 				DE_ASSERT(isStageFlagAllowed(pBufferMemoryBarrier.dstStageMask));
618 				DE_ASSERT(isAccessFlagAllowed(pBufferMemoryBarrier.srcAccessMask));
619 				DE_ASSERT(isAccessFlagAllowed(pBufferMemoryBarrier.dstAccessMask));
620 
621 				srcStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.srcStageMask);
622 				dstStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.dstStageMask);
623 				bufferMemoryBarriers.push_back(makeBufferMemoryBarrier(
624 					static_cast<VkAccessFlags>(pBufferMemoryBarrier.srcAccessMask),
625 					static_cast<VkAccessFlags>(pBufferMemoryBarrier.dstAccessMask),
626 					pBufferMemoryBarrier.buffer,
627 					pBufferMemoryBarrier.offset,
628 					pBufferMemoryBarrier.size,
629 					pBufferMemoryBarrier.srcQueueFamilyIndex,
630 					pBufferMemoryBarrier.dstQueueFamilyIndex
631 				));
632 			}
633 			pBufferMemoryBarriers = &bufferMemoryBarriers[0];
634 		}
635 
636 		// translate VkImageMemoryBarrier2KHR to VkImageMemoryBarrier
637 		std::vector<VkImageMemoryBarrier> imageMemoryBarriers;
638 		if (imageMemoryBarrierCount)
639 		{
640 			imageMemoryBarriers.reserve(imageMemoryBarrierCount);
641 			for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
642 			{
643 				const VkImageMemoryBarrier2KHR& pImageMemoryBarrier = pDependencyInfo->pImageMemoryBarriers[i];
644 
645 				DE_ASSERT(isStageFlagAllowed(pImageMemoryBarrier.srcStageMask));
646 				DE_ASSERT(isStageFlagAllowed(pImageMemoryBarrier.dstStageMask));
647 				DE_ASSERT(isAccessFlagAllowed(pImageMemoryBarrier.srcAccessMask));
648 				DE_ASSERT(isAccessFlagAllowed(pImageMemoryBarrier.dstAccessMask));
649 
650 				srcStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.srcStageMask);
651 				dstStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.dstStageMask);
652 				imageMemoryBarriers.push_back(makeImageMemoryBarrier(
653 					static_cast<VkAccessFlags>(pImageMemoryBarrier.srcAccessMask),
654 					static_cast<VkAccessFlags>(pImageMemoryBarrier.dstAccessMask),
655 					pImageMemoryBarrier.oldLayout,
656 					pImageMemoryBarrier.newLayout,
657 					pImageMemoryBarrier.image,
658 					pImageMemoryBarrier.subresourceRange,
659 					pImageMemoryBarrier.srcQueueFamilyIndex,
660 					pImageMemoryBarrier.dstQueueFamilyIndex
661 				));
662 			}
663 			pImageMemoryBarriers = &imageMemoryBarriers[0];
664 		}
665 
666 		m_vk.cmdPipelineBarrier(
667 			commandBuffer,
668 			srcStageMask,
669 			dstStageMask,
670 			(VkDependencyFlags)0,
671 			memoryBarrierCount,
672 			pMemoryBarriers,
673 			bufferMemoryBarrierCount,
674 			pBufferMemoryBarriers,
675 			imageMemoryBarrierCount,
676 			pImageMemoryBarriers
677 		);
678 	}
679 
cmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,const VkDependencyInfoKHR * pDependencyInfo) const680 	void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
681 	{
682 		DE_ASSERT(pDependencyInfo);
683 
684 		VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
685 		if (pDependencyInfo->pMemoryBarriers)
686 			srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
687 		if (pDependencyInfo->pBufferMemoryBarriers)
688 			srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
689 		if (pDependencyInfo->pImageMemoryBarriers)
690 			srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
691 
692 		DE_ASSERT(isStageFlagAllowed(srcStageMask));
693 		m_vk.cmdSetEvent(commandBuffer, event, static_cast<VkPipelineStageFlags>(srcStageMask));
694 	}
695 
cmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags2KHR flag) const696 	void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) const override
697 	{
698 		DE_ASSERT(isStageFlagAllowed(flag));
699 		VkPipelineStageFlags legacyStageMask = static_cast<VkPipelineStageFlags>(flag);
700 		m_vk.cmdResetEvent(commandBuffer, event, legacyStageMask);
701 	}
702 
cmdWaitEvents(VkCommandBuffer commandBuffer,deUint32 eventCount,const VkEvent * pEvents,const VkDependencyInfoKHR * pDependencyInfo) const703 	void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
704 	{
705 		DE_ASSERT(pDependencyInfo);
706 
707 		VkPipelineStageFlags2KHR			srcStageMask				= VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
708 		VkPipelineStageFlags2KHR			dstStageMask				= VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
709 		deUint32							memoryBarrierCount			= pDependencyInfo->memoryBarrierCount;
710 		deUint32							bufferMemoryBarrierCount	= pDependencyInfo->bufferMemoryBarrierCount;
711 		deUint32							imageMemoryBarrierCount		= pDependencyInfo->imageMemoryBarrierCount;
712 		VkMemoryBarrier*					pMemoryBarriers				= DE_NULL;
713 		VkBufferMemoryBarrier*				pBufferMemoryBarriers		= DE_NULL;
714 		VkImageMemoryBarrier*				pImageMemoryBarriers		= DE_NULL;
715 		std::vector<VkMemoryBarrier>		memoryBarriers;
716 		std::vector<VkBufferMemoryBarrier>	bufferMemoryBarriers;
717 		std::vector<VkImageMemoryBarrier>	imageMemoryBarriers;
718 
719 		if (pDependencyInfo->pMemoryBarriers)
720 		{
721 			srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
722 			dstStageMask = pDependencyInfo->pMemoryBarriers[0].dstStageMask;
723 
724 			memoryBarriers.reserve(memoryBarrierCount);
725 			for (deUint32 i = 0; i < memoryBarrierCount; ++i)
726 			{
727 				const VkMemoryBarrier2KHR& mb = pDependencyInfo->pMemoryBarriers[i];
728 				DE_ASSERT(isAccessFlagAllowed(mb.srcAccessMask));
729 				DE_ASSERT(isAccessFlagAllowed(mb.dstAccessMask));
730 				memoryBarriers.push_back(
731 					makeMemoryBarrier(
732 						static_cast<VkAccessFlags>(mb.srcAccessMask),
733 						static_cast<VkAccessFlags>(mb.dstAccessMask)
734 					)
735 				);
736 			}
737 			pMemoryBarriers = &memoryBarriers[0];
738 		}
739 		if (pDependencyInfo->pBufferMemoryBarriers)
740 		{
741 			srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
742 			dstStageMask = pDependencyInfo->pBufferMemoryBarriers[0].dstStageMask;
743 
744 			bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
745 			for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
746 			{
747 				const VkBufferMemoryBarrier2KHR& bmb = pDependencyInfo->pBufferMemoryBarriers[i];
748 				DE_ASSERT(isAccessFlagAllowed(bmb.srcAccessMask));
749 				DE_ASSERT(isAccessFlagAllowed(bmb.dstAccessMask));
750 				bufferMemoryBarriers.push_back(
751 					makeBufferMemoryBarrier(
752 						static_cast<VkAccessFlags>(bmb.srcAccessMask),
753 						static_cast<VkAccessFlags>(bmb.dstAccessMask),
754 						bmb.buffer,
755 						bmb.offset,
756 						bmb.size,
757 						bmb.srcQueueFamilyIndex,
758 						bmb.dstQueueFamilyIndex
759 					)
760 				);
761 			}
762 			pBufferMemoryBarriers = &bufferMemoryBarriers[0];
763 		}
764 		if (pDependencyInfo->pImageMemoryBarriers)
765 		{
766 			srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
767 			dstStageMask = pDependencyInfo->pImageMemoryBarriers[0].dstStageMask;
768 
769 			imageMemoryBarriers.reserve(imageMemoryBarrierCount);
770 			for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
771 			{
772 				const VkImageMemoryBarrier2KHR& imb = pDependencyInfo->pImageMemoryBarriers[i];
773 				DE_ASSERT(isAccessFlagAllowed(imb.srcAccessMask));
774 				DE_ASSERT(isAccessFlagAllowed(imb.dstAccessMask));
775 				imageMemoryBarriers.push_back(
776 					makeImageMemoryBarrier(
777 						static_cast<VkAccessFlags>(imb.srcAccessMask),
778 						static_cast<VkAccessFlags>(imb.dstAccessMask),
779 						imb.oldLayout,
780 						imb.newLayout,
781 						imb.image,
782 						imb.subresourceRange,
783 						imb.srcQueueFamilyIndex,
784 						imb.dstQueueFamilyIndex
785 					)
786 				);
787 			}
788 			pImageMemoryBarriers = &imageMemoryBarriers[0];
789 		}
790 
791 		DE_ASSERT(isStageFlagAllowed(srcStageMask));
792 		DE_ASSERT(isStageFlagAllowed(dstStageMask));
793 		m_vk.cmdWaitEvents(commandBuffer, eventCount, pEvents,
794 			static_cast<VkPipelineStageFlags>(srcStageMask), static_cast<VkPipelineStageFlags>(dstStageMask),
795 			memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
796 	}
797 
queueSubmit(VkQueue queue,VkFence fence)798 	VkResult queueSubmit(VkQueue queue, VkFence fence) override
799 	{
800 		// make sure submit info was added
801 		DE_ASSERT(!m_submitInfoData.empty());
802 
803 		// make sure separate LegacySynchronizationWrapper is created per single submit
804 		DE_ASSERT(!m_submited);
805 
806 		std::vector<VkSubmitInfo> submitInfo(m_submitInfoData.size(), { VK_STRUCTURE_TYPE_SUBMIT_INFO, DE_NULL, 0u, DE_NULL, DE_NULL, 0u, DE_NULL, 0u, DE_NULL });
807 
808 		std::vector<VkTimelineSemaphoreSubmitInfo> timelineSemaphoreSubmitInfo;
809 		timelineSemaphoreSubmitInfo.reserve(m_submitInfoData.size());
810 
811 		// translate indexes from m_submitInfoData to pointers and construct VkSubmitInfo
812 		for (deUint32 i = 0; i < m_submitInfoData.size(); ++i)
813 		{
814 			auto&			data	= m_submitInfoData[i];
815 			VkSubmitInfo&	si		= submitInfo[i];
816 
817 			si.waitSemaphoreCount	= data.waitSemaphoreCount;
818 			si.commandBufferCount	= data.commandBufferCount;
819 			si.signalSemaphoreCount	= data.signalSemaphoreCount;
820 
821 			if (data.waitSemaphoreValueIndexPlusOne || data.signalSemaphoreValueIndexPlusOne)
822 			{
823 				deUint64* pWaitSemaphoreValues = DE_NULL;
824 				if (data.waitSemaphoreValueIndexPlusOne)
825 					pWaitSemaphoreValues = &m_timelineSemaphoreValues[data.waitSemaphoreValueIndexPlusOne - 1];
826 
827 				deUint64* pSignalSemaphoreValues = DE_NULL;
828 				if (data.signalSemaphoreValueIndexPlusOne)
829 					pSignalSemaphoreValues = &m_timelineSemaphoreValues[data.signalSemaphoreValueIndexPlusOne - 1];
830 
831 				timelineSemaphoreSubmitInfo.push_back({
832 					VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,		// VkStructureType	sType;
833 					DE_NULL,												// const void*		pNext;
834 					data.waitSemaphoreCount,								// deUint32			waitSemaphoreValueCount
835 					pWaitSemaphoreValues,									// const deUint64*	pWaitSemaphoreValues
836 					data.signalSemaphoreCount,								// deUint32			signalSemaphoreValueCount
837 					pSignalSemaphoreValues									// const deUint64*	pSignalSemaphoreValues
838 				});
839 				si.pNext = &timelineSemaphoreSubmitInfo.back();
840 			}
841 
842 			if (data.waitSemaphoreCount)
843 			{
844 				si.pWaitSemaphores		= &m_waitSemaphores[data.waitSemaphoreIndex];
845 				si.pWaitDstStageMask	= &m_waitDstStageMasks[data.waitSemaphoreIndex];
846 			}
847 
848 			if (data.commandBufferCount)
849 				si.pCommandBuffers = &m_commandBuffers[data.commandBufferIndex];
850 
851 			if (data.signalSemaphoreCount)
852 				si.pSignalSemaphores = &m_signalSemaphores[data.signalSemaphoreIndex];
853 		}
854 
855 		m_submited = DE_TRUE;
856 		return m_vk.queueSubmit(queue, static_cast<deUint32>(submitInfo.size()), &submitInfo[0], fence);
857 	}
858 
859 protected:
860 
861 	std::vector<VkSemaphore>			m_waitSemaphores;
862 	std::vector<VkSemaphore>			m_signalSemaphores;
863 	std::vector<VkPipelineStageFlags>	m_waitDstStageMasks;
864 	std::vector<VkCommandBuffer>		m_commandBuffers;
865 	std::vector<SubmitInfoData>			m_submitInfoData;
866 	std::vector<deUint64>				m_timelineSemaphoreValues;
867 	bool								m_submited;
868 };
869 
870 class Synchronization2Wrapper : public SynchronizationWrapperBase
871 {
872 public:
Synchronization2Wrapper(const DeviceInterface & vk,deUint32 submitInfoCount)873 	Synchronization2Wrapper(const DeviceInterface& vk, deUint32 submitInfoCount)
874 		: SynchronizationWrapperBase(vk)
875 	{
876 		m_submitInfo.reserve(submitInfoCount);
877 	}
878 
879 	~Synchronization2Wrapper() = default;
880 
addSubmitInfo(deUint32 waitSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pWaitSemaphoreInfos,deUint32 commandBufferInfoCount,const VkCommandBufferSubmitInfoKHR * pCommandBufferInfos,deUint32 signalSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pSignalSemaphoreInfos,bool usingWaitTimelineSemaphore,bool usingSignalTimelineSemaphore)881 	void addSubmitInfo(deUint32								waitSemaphoreInfoCount,
882 					   const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos,
883 					   deUint32								commandBufferInfoCount,
884 					   const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos,
885 					   deUint32								signalSemaphoreInfoCount,
886 					   const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos,
887 					   bool									usingWaitTimelineSemaphore,
888 					   bool									usingSignalTimelineSemaphore) override
889 	{
890 		DE_UNREF(usingWaitTimelineSemaphore);
891 		DE_UNREF(usingSignalTimelineSemaphore);
892 
893 		m_submitInfo.push_back(VkSubmitInfo2KHR{
894 			VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR,		// VkStructureType						sType
895 			DE_NULL,									// const void*							pNext
896 			0u,											// VkSubmitFlagsKHR						flags
897 			waitSemaphoreInfoCount,						// deUint32								waitSemaphoreInfoCount
898 			pWaitSemaphoreInfos,						// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
899 			commandBufferInfoCount,						// deUint32								commandBufferInfoCount
900 			pCommandBufferInfos,						// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
901 			signalSemaphoreInfoCount,					// deUint32								signalSemaphoreInfoCount
902 			pSignalSemaphoreInfos						// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
903 		});
904 	}
905 
cmdPipelineBarrier(VkCommandBuffer commandBuffer,const VkDependencyInfoKHR * pDependencyInfo) const906 	void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
907 	{
908 		m_vk.cmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo);
909 	}
910 
cmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,const VkDependencyInfoKHR * pDependencyInfo) const911 	void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
912 	{
913 		m_vk.cmdSetEvent2KHR(commandBuffer, event, pDependencyInfo);
914 	}
915 
cmdWaitEvents(VkCommandBuffer commandBuffer,deUint32 eventCount,const VkEvent * pEvents,const VkDependencyInfoKHR * pDependencyInfo) const916 	void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
917 	{
918 		m_vk.cmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfo);
919 	}
920 
cmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags2KHR flag) const921 	void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) const override
922 	{
923 		m_vk.cmdResetEvent2KHR(commandBuffer, event, flag);
924 	}
925 
queueSubmit(VkQueue queue,VkFence fence)926 	VkResult queueSubmit(VkQueue queue, VkFence fence) override
927 	{
928 		return m_vk.queueSubmit2KHR(queue, static_cast<deUint32>(m_submitInfo.size()), &m_submitInfo[0], fence);
929 	}
930 
931 protected:
932 
933 	std::vector<VkSubmitInfo2KHR> m_submitInfo;
934 };
935 
getSynchronizationWrapper(SynchronizationType type,const DeviceInterface & vk,bool usingTimelineSemaphores,deUint32 submitInfoCount)936 SynchronizationWrapperPtr getSynchronizationWrapper(SynchronizationType		type,
937 													const DeviceInterface&	vk,
938 													bool					usingTimelineSemaphores,
939 													deUint32				submitInfoCount)
940 {
941 	return (type == SynchronizationType::LEGACY)
942 		? SynchronizationWrapperPtr(new LegacySynchronizationWrapper(vk, usingTimelineSemaphores, submitInfoCount))
943 		: SynchronizationWrapperPtr(new Synchronization2Wrapper(vk, submitInfoCount));
944 }
945 
submitCommandsAndWait(SynchronizationWrapperPtr synchronizationWrapper,const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer cmdBuffer)946 void submitCommandsAndWait(SynchronizationWrapperPtr	synchronizationWrapper,
947 						   const DeviceInterface&		vk,
948 						   const VkDevice				device,
949 						   const VkQueue				queue,
950 						   const VkCommandBuffer		cmdBuffer)
951 {
952 	VkCommandBufferSubmitInfoKHR commandBufferInfoCount = makeCommonCommandBufferSubmitInfo(cmdBuffer);
953 
954 	synchronizationWrapper->addSubmitInfo(
955 		0u,										// deUint32								waitSemaphoreInfoCount
956 		DE_NULL,								// const VkSemaphoreSubmitInfoKHR*		pWaitSemaphoreInfos
957 		1u,										// deUint32								commandBufferInfoCount
958 		&commandBufferInfoCount,				// const VkCommandBufferSubmitInfoKHR*	pCommandBufferInfos
959 		0u,										// deUint32								signalSemaphoreInfoCount
960 		DE_NULL									// const VkSemaphoreSubmitInfoKHR*		pSignalSemaphoreInfos
961 	);
962 
963 	const Unique<VkFence> fence(createFence(vk, device));
964 	VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
965 	VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
966 }
967 
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)968 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
969 {
970 	const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
971 
972 	if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
973 		throw tcu::NotSupportedError("Tessellation shader not supported");
974 
975 	if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
976 		throw tcu::NotSupportedError("Geometry shader not supported");
977 
978 	if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
979 		throw tcu::NotSupportedError("Double-precision floats not supported");
980 
981 	if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
982 		throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
983 
984 	if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
985 		throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
986 
987 	if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
988 		throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
989 }
990 
requireStorageImageSupport(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat fmt)991 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
992 {
993 	const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
994 	if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
995 		throw tcu::NotSupportedError("Storage image format not supported");
996 }
997 
getResourceName(const ResourceDescription & resource)998 std::string getResourceName (const ResourceDescription& resource)
999 {
1000 	std::ostringstream str;
1001 
1002 	if ((resource.type == RESOURCE_TYPE_BUFFER) ||
1003 		(resource.type == RESOURCE_TYPE_INDEX_BUFFER))
1004 	{
1005 		str << "buffer_" << resource.size.x();
1006 	}
1007 	else if (resource.type == RESOURCE_TYPE_IMAGE)
1008 	{
1009 		str << "image_" << resource.size.x()
1010 						<< (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
1011 						<< (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
1012 			<< "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
1013 	}
1014 	else if (isIndirectBuffer(resource.type))
1015 		str << "indirect_buffer";
1016 	else
1017 		DE_ASSERT(0);
1018 
1019 	return str.str();
1020 }
1021 
isIndirectBuffer(const ResourceType type)1022 bool isIndirectBuffer (const ResourceType type)
1023 {
1024 	switch (type)
1025 	{
1026 		case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
1027 		case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
1028 		case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
1029 			return true;
1030 
1031 		default:
1032 			return false;
1033 	}
1034 }
1035 
makeCommonCommandBufferSubmitInfo(const VkCommandBuffer cmdBuf)1036 VkCommandBufferSubmitInfoKHR makeCommonCommandBufferSubmitInfo (const VkCommandBuffer cmdBuf)
1037 {
1038 	return
1039 	{
1040 		VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR,	// VkStructureType		sType
1041 		DE_NULL,											// const void*			pNext
1042 		cmdBuf,												// VkCommandBuffer		commandBuffer
1043 		0u													// uint32_t				deviceMask
1044 	};
1045 }
1046 
makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore,deUint64 value,VkPipelineStageFlags2KHR stageMask)1047 VkSemaphoreSubmitInfoKHR makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore, deUint64 value, VkPipelineStageFlags2KHR stageMask)
1048 {
1049 	return
1050 	{
1051 		VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,	// VkStructureType				sType
1052 		DE_NULL,										// const void*					pNext
1053 		semaphore,										// VkSemaphore					semaphore
1054 		value,											// deUint64						value
1055 		stageMask,										// VkPipelineStageFlags2KHR		stageMask
1056 		0u												// deUint32						deviceIndex
1057 	};
1058 }
1059 
makeCommonDependencyInfo(const VkMemoryBarrier2KHR * pMemoryBarrier,const VkBufferMemoryBarrier2KHR * pBufferMemoryBarrier,const VkImageMemoryBarrier2KHR * pImageMemoryBarrier)1060 VkDependencyInfoKHR makeCommonDependencyInfo(const VkMemoryBarrier2KHR* pMemoryBarrier, const VkBufferMemoryBarrier2KHR* pBufferMemoryBarrier, const VkImageMemoryBarrier2KHR* pImageMemoryBarrier)
1061 {
1062 	return
1063 	{
1064 		VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR,		// VkStructureType					sType
1065 		DE_NULL,									// const void*						pNext
1066 		VK_DEPENDENCY_BY_REGION_BIT,				// VkDependencyFlags				dependencyFlags
1067 		!!pMemoryBarrier,							// deUint32							memoryBarrierCount
1068 		pMemoryBarrier,								// const VkMemoryBarrier2KHR*		pMemoryBarriers
1069 		!!pBufferMemoryBarrier,						// deUint32							bufferMemoryBarrierCount
1070 		pBufferMemoryBarrier,						// const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers
1071 		!!pImageMemoryBarrier,						// deUint32							imageMemoryBarrierCount
1072 		pImageMemoryBarrier							// const VkImageMemoryBarrier2KHR*	pImageMemoryBarriers
1073 	};
1074 }
1075 
PipelineCacheData(void)1076 PipelineCacheData::PipelineCacheData (void)
1077 {
1078 }
1079 
~PipelineCacheData(void)1080 PipelineCacheData::~PipelineCacheData (void)
1081 {
1082 }
1083 
createPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device) const1084 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
1085 {
1086 	const de::ScopedLock						dataLock	(m_lock);
1087 	const struct vk::VkPipelineCacheCreateInfo	params	=
1088 	{
1089 		vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1090 		DE_NULL,
1091 		(vk::VkPipelineCacheCreateFlags)0,
1092 		(deUintptr)m_data.size(),
1093 		(m_data.empty() ? DE_NULL : &m_data[0])
1094 	};
1095 
1096 	return vk::createPipelineCache(vk, device, &params);
1097 }
1098 
setFromPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineCache pipelineCache)1099 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
1100 {
1101 	const de::ScopedLock		dataLock		(m_lock);
1102 	deUintptr					dataSize		= 0;
1103 
1104 	VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
1105 
1106 	m_data.resize(dataSize);
1107 
1108 	if (dataSize > 0)
1109 		VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
1110 }
1111 
1112 } // synchronization
1113 } // vkt
1114