Use proper image tiling in synchronization test support checks
[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 #include <limits>
31
32 namespace vkt
33 {
34 namespace synchronization
35 {
36 using namespace vk;
37
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
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
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
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
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
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>
214 inline const T* dataPointer (const std::vector<T>& vec)
215 {
216         return (vec.size() != 0 ? &vec[0] : DE_NULL);
217 }
218
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
403         bool isStageFlagAllowed(VkPipelineStageFlags2KHR 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_KHR,
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
448         bool isAccessFlagAllowed(VkAccessFlags2KHR 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_KHR,
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:
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
512         void addSubmitInfo(deUint32                                                             waitSemaphoreInfoCount,
513                                            const VkSemaphoreSubmitInfoKHR*              pWaitSemaphoreInfos,
514                                            deUint32                                                             commandBufferInfoCount,
515                                            const VkCommandBufferSubmitInfoKHR*  pCommandBufferInfos,
516                                            deUint32                                                             signalSemaphoreInfoCount,
517                                            const VkSemaphoreSubmitInfoKHR*              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
571         void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
572         {
573                 DE_ASSERT(pDependencyInfo);
574
575                 VkPipelineStageFlags    srcStageMask                            = VK_PIPELINE_STAGE_NONE_KHR;
576                 VkPipelineStageFlags    dstStageMask                            = VK_PIPELINE_STAGE_NONE_KHR;
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 VkMemoryBarrier2KHR 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 VkMemoryBarrier2KHR& 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 VkBufferMemoryBarrier2KHR 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 VkBufferMemoryBarrier2KHR& 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 VkImageMemoryBarrier2KHR 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 VkImageMemoryBarrier2KHR& 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
681         void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
682         {
683                 DE_ASSERT(pDependencyInfo);
684
685                 VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
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
697         void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR 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
704         void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
705         {
706                 DE_ASSERT(pDependencyInfo);
707
708                 VkPipelineStageFlags2KHR                        srcStageMask                            = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
709                 VkPipelineStageFlags2KHR                        dstStageMask                            = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
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 VkMemoryBarrier2KHR& 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 VkBufferMemoryBarrier2KHR& 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 VkImageMemoryBarrier2KHR& 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
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:
874         Synchronization2Wrapper(const DeviceInterface& vk, deUint32 submitInfoCount)
875                 : SynchronizationWrapperBase(vk)
876         {
877                 m_submitInfo.reserve(submitInfoCount);
878         }
879
880         ~Synchronization2Wrapper() = default;
881
882         void addSubmitInfo(deUint32                                                             waitSemaphoreInfoCount,
883                                            const VkSemaphoreSubmitInfoKHR*              pWaitSemaphoreInfos,
884                                            deUint32                                                             commandBufferInfoCount,
885                                            const VkCommandBufferSubmitInfoKHR*  pCommandBufferInfos,
886                                            deUint32                                                             signalSemaphoreInfoCount,
887                                            const VkSemaphoreSubmitInfoKHR*              pSignalSemaphoreInfos,
888                                            bool                                                                 usingWaitTimelineSemaphore,
889                                            bool                                                                 usingSignalTimelineSemaphore) override
890         {
891                 DE_UNREF(usingWaitTimelineSemaphore);
892                 DE_UNREF(usingSignalTimelineSemaphore);
893
894                 m_submitInfo.push_back(VkSubmitInfo2KHR{
895                         VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR,            // VkStructureType                                              sType
896                         DE_NULL,                                                                        // const void*                                                  pNext
897                         0u,                                                                                     // VkSubmitFlagsKHR                                             flags
898                         waitSemaphoreInfoCount,                                         // deUint32                                                             waitSemaphoreInfoCount
899                         pWaitSemaphoreInfos,                                            // const VkSemaphoreSubmitInfoKHR*              pWaitSemaphoreInfos
900                         commandBufferInfoCount,                                         // deUint32                                                             commandBufferInfoCount
901                         pCommandBufferInfos,                                            // const VkCommandBufferSubmitInfoKHR*  pCommandBufferInfos
902                         signalSemaphoreInfoCount,                                       // deUint32                                                             signalSemaphoreInfoCount
903                         pSignalSemaphoreInfos                                           // const VkSemaphoreSubmitInfoKHR*              pSignalSemaphoreInfos
904                 });
905         }
906
907         void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
908         {
909                 m_vk.cmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo);
910         }
911
912         void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
913         {
914                 m_vk.cmdSetEvent2KHR(commandBuffer, event, pDependencyInfo);
915         }
916
917         void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
918         {
919                 m_vk.cmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfo);
920         }
921
922         void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) const override
923         {
924                 m_vk.cmdResetEvent2KHR(commandBuffer, event, flag);
925         }
926
927         VkResult queueSubmit(VkQueue queue, VkFence fence) override
928         {
929                 return m_vk.queueSubmit2KHR(queue, static_cast<deUint32>(m_submitInfo.size()), &m_submitInfo[0], fence);
930         }
931
932 protected:
933
934         std::vector<VkSubmitInfo2KHR> m_submitInfo;
935 };
936
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
947 void submitCommandsAndWait(SynchronizationWrapperPtr    synchronizationWrapper,
948                                                    const DeviceInterface&               vk,
949                                                    const VkDevice                               device,
950                                                    const VkQueue                                queue,
951                                                    const VkCommandBuffer                cmdBuffer)
952 {
953         VkCommandBufferSubmitInfoKHR commandBufferInfoCount = makeCommonCommandBufferSubmitInfo(cmdBuffer);
954
955         synchronizationWrapper->addSubmitInfo(
956                 0u,                                                                             // deUint32                                                             waitSemaphoreInfoCount
957                 DE_NULL,                                                                // const VkSemaphoreSubmitInfoKHR*              pWaitSemaphoreInfos
958                 1u,                                                                             // deUint32                                                             commandBufferInfoCount
959                 &commandBufferInfoCount,                                // const VkCommandBufferSubmitInfoKHR*  pCommandBufferInfos
960                 0u,                                                                             // deUint32                                                             signalSemaphoreInfoCount
961                 DE_NULL                                                                 // const VkSemaphoreSubmitInfoKHR*              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
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
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
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
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
1039 VkCommandBufferSubmitInfoKHR makeCommonCommandBufferSubmitInfo (const VkCommandBuffer cmdBuf)
1040 {
1041         return
1042         {
1043                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR,       // VkStructureType              sType
1044                 DE_NULL,                                                                                        // const void*                  pNext
1045                 cmdBuf,                                                                                         // VkCommandBuffer              commandBuffer
1046                 0u                                                                                                      // uint32_t                             deviceMask
1047         };
1048 }
1049
1050 VkSemaphoreSubmitInfoKHR makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore, deUint64 value, VkPipelineStageFlags2KHR stageMask)
1051 {
1052         return
1053         {
1054                 VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR,    // VkStructureType                              sType
1055                 DE_NULL,                                                                                // const void*                                  pNext
1056                 semaphore,                                                                              // VkSemaphore                                  semaphore
1057                 value,                                                                                  // deUint64                                             value
1058                 stageMask,                                                                              // VkPipelineStageFlags2KHR             stageMask
1059                 0u                                                                                              // deUint32                                             deviceIndex
1060         };
1061 }
1062
1063 VkDependencyInfoKHR makeCommonDependencyInfo(const VkMemoryBarrier2KHR* pMemoryBarrier, const VkBufferMemoryBarrier2KHR* pBufferMemoryBarrier, const VkImageMemoryBarrier2KHR* pImageMemoryBarrier,
1064                                                                                          bool eventDependency)
1065 {
1066         return
1067         {
1068                 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR,                          // 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
1080 PipelineCacheData::PipelineCacheData (void)
1081 {
1082 }
1083
1084 PipelineCacheData::~PipelineCacheData (void)
1085 {
1086 }
1087
1088 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
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