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