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