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