Merge vk-gl-cts/vulkan-cts-1.1.6 into vk-gl-cts/vulkan-cts-1.2.1
[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 "deStringUtil.hpp"
28
29 namespace vkt
30 {
31 namespace synchronization
32 {
33 using namespace vk;
34
35 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
36 {
37         const VkCommandBufferAllocateInfo info =
38         {
39                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
40                 DE_NULL,                                                                                        // const void*                  pNext;
41                 commandPool,                                                                            // VkCommandPool                commandPool;
42                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
43                 1u,                                                                                                     // deUint32                             commandBufferCount;
44         };
45         return allocateCommandBuffer(vk, device, &info);
46 }
47
48 Move<VkPipeline> makeComputePipeline (const DeviceInterface&            vk,
49                                                                           const VkDevice                                device,
50                                                                           const VkPipelineLayout                pipelineLayout,
51                                                                           const VkShaderModule                  shaderModule,
52                                                                           const VkSpecializationInfo*   specInfo,
53                                                                           PipelineCacheData&                    pipelineCacheData)
54 {
55         const VkPipelineShaderStageCreateInfo shaderStageInfo =
56         {
57                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
58                 DE_NULL,                                                                                                // const void*                                          pNext;
59                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags     flags;
60                 VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
61                 shaderModule,                                                                                   // VkShaderModule                                       module;
62                 "main",                                                                                                 // const char*                                          pName;
63                 specInfo,                                                                                               // const VkSpecializationInfo*          pSpecializationInfo;
64         };
65         const VkComputePipelineCreateInfo pipelineInfo =
66         {
67                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                      sType;
68                 DE_NULL,                                                                                        // const void*                                          pNext;
69                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                        flags;
70                 shaderStageInfo,                                                                        // VkPipelineShaderStageCreateInfo      stage;
71                 pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
72                 DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
73                 0,                                                                                                      // deInt32                                                      basePipelineIndex;
74         };
75
76         {
77                 const vk::Unique<vk::VkPipelineCache>   pipelineCache   (pipelineCacheData.createPipelineCache(vk, device));
78                 vk::Move<vk::VkPipeline>                                pipeline                (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
79
80                 // Refresh data from cache
81                 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
82
83                 return pipeline;
84         }
85 }
86
87 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
88 {
89         const VkImageCreateInfo imageInfo =
90         {
91                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
92                 DE_NULL,                                                                        // const void*              pNext;
93                 (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
94                 imageType,                                                                      // VkImageType              imageType;
95                 format,                                                                         // VkFormat                 format;
96                 extent,                                                                         // VkExtent3D               extent;
97                 1u,                                                                                     // uint32_t                 mipLevels;
98                 1u,                                                                                     // uint32_t                 arrayLayers;
99                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
100                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
101                 usage,                                                                          // VkImageUsageFlags        usage;
102                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
103                 0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
104                 DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
105                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
106         };
107         return imageInfo;
108 }
109
110 void beginRenderPassWithRasterizationDisabled (const DeviceInterface&   vk,
111                                                                                            const VkCommandBuffer        commandBuffer,
112                                                                                            const VkRenderPass           renderPass,
113                                                                                            const VkFramebuffer          framebuffer)
114 {
115         const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
116
117         beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
118 }
119
120 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&                     vk,
121                                                                                                                          const VkDevice                                 device,
122                                                                                                                          const VkShaderStageFlagBits    stage,
123                                                                                                                          const ProgramBinary&                   binary,
124                                                                                                                          const VkSpecializationInfo*    specInfo)
125 {
126         VkShaderModule module;
127         switch (stage)
128         {
129                 case (VK_SHADER_STAGE_VERTEX_BIT):
130                         DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
131                         m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
132                         module = *m_vertexShaderModule;
133                         break;
134
135                 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
136                         DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
137                         m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
138                         module = *m_tessControlShaderModule;
139                         break;
140
141                 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
142                         DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
143                         m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
144                         module = *m_tessEvaluationShaderModule;
145                         break;
146
147                 case (VK_SHADER_STAGE_GEOMETRY_BIT):
148                         DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
149                         m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
150                         module = *m_geometryShaderModule;
151                         break;
152
153                 case (VK_SHADER_STAGE_FRAGMENT_BIT):
154                         DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
155                         m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
156                         module = *m_fragmentShaderModule;
157                         break;
158
159                 default:
160                         DE_FATAL("Invalid shader stage");
161                         return *this;
162         }
163
164         const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
165         {
166                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
167                 DE_NULL,                                                                                                // const void*                                                  pNext;
168                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
169                 stage,                                                                                                  // VkShaderStageFlagBits                                stage;
170                 module,                                                                                                 // VkShaderModule                                               module;
171                 "main",                                                                                                 // const char*                                                  pName;
172                 specInfo,                                                                                               // const VkSpecializationInfo*                  pSpecializationInfo;
173         };
174
175         m_shaderStageFlags |= stage;
176         m_shaderStages.push_back(pipelineShaderStageInfo);
177
178         return *this;
179 }
180
181 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
182 {
183         const VkVertexInputBindingDescription bindingDesc =
184         {
185                 0u,                                                                     // uint32_t                             binding;
186                 stride,                                                         // uint32_t                             stride;
187                 VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
188         };
189         const VkVertexInputAttributeDescription attributeDesc =
190         {
191                 0u,                                                                     // uint32_t                     location;
192                 0u,                                                                     // uint32_t                     binding;
193                 vertexFormat,                                           // VkFormat                     format;
194                 0u,                                                                     // uint32_t                     offset;
195         };
196
197         m_vertexInputBindings.clear();
198         m_vertexInputBindings.push_back(bindingDesc);
199
200         m_vertexInputAttributes.clear();
201         m_vertexInputAttributes.push_back(attributeDesc);
202
203         return *this;
204 }
205
206 template<typename T>
207 inline const T* dataPointer (const std::vector<T>& vec)
208 {
209         return (vec.size() != 0 ? &vec[0] : DE_NULL);
210 }
211
212 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
213                                                                                                  const VkDevice                 device,
214                                                                                                  const VkPipelineLayout pipelineLayout,
215                                                                                                  const VkRenderPass             renderPass,
216                                                                                                  PipelineCacheData&             pipelineCacheData)
217 {
218         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
219         {
220                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
221                 DE_NULL,                                                                                                                // const void*                                 pNext;
222                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
223                 static_cast<deUint32>(m_vertexInputBindings.size()),                    // uint32_t                                    vertexBindingDescriptionCount;
224                 dataPointer(m_vertexInputBindings),                                                             // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
225                 static_cast<deUint32>(m_vertexInputAttributes.size()),                  // uint32_t                                    vertexAttributeDescriptionCount;
226                 dataPointer(m_vertexInputAttributes),                                                   // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
227         };
228
229         const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
230                                                                                                                                                                                                                  : m_primitiveTopology;
231         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
232         {
233                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
234                 DE_NULL,                                                                                                                // const void*                                 pNext;
235                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
236                 topology,                                                                                                               // VkPrimitiveTopology                         topology;
237                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
238         };
239
240         const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
241         {
242                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                             sType;
243                 DE_NULL,                                                                                                                // const void*                                 pNext;
244                 (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags      flags;
245                 m_patchControlPoints,                                                                                   // uint32_t                                    patchControlPoints;
246         };
247
248         const VkViewport        viewport        = makeViewport(m_renderSize);
249         const VkRect2D          scissor         = makeRect2D(m_renderSize);
250
251         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
252         {
253                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
254                 DE_NULL,                                                                                                // const void*                                 pNext;
255                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
256                 1u,                                                                                                             // uint32_t                                    viewportCount;
257                 &viewport,                                                                                              // const VkViewport*                           pViewports;
258                 1u,                                                                                                             // uint32_t                                    scissorCount;
259                 &scissor,                                                                                               // const VkRect2D*                             pScissors;
260         };
261
262         const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
263         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
264         {
265                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
266                 DE_NULL,                                                                                                                // const void*                              pNext;
267                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
268                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
269                 isRasterizationDisabled,                                                                                // VkBool32                                 rasterizerDiscardEnable;
270                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
271                 m_cullModeFlags,                                                                                                // VkCullModeFlags                                                      cullMode;
272                 m_frontFace,                                                                                                    // VkFrontFace                                                          frontFace;
273                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
274                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
275                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
276                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
277                 1.0f,                                                                                                                   // float                                                                        lineWidth;
278         };
279
280         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
281         {
282                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
283                 DE_NULL,                                                                                                        // const void*                                                          pNext;
284                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
285                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
286                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
287                 0.0f,                                                                                                           // float                                                                        minSampleShading;
288                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
289                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
290                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
291         };
292
293         const VkStencilOpState stencilOpState = makeStencilOpState(
294                 VK_STENCIL_OP_KEEP,             // stencil fail
295                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
296                 VK_STENCIL_OP_KEEP,             // depth only fail
297                 VK_COMPARE_OP_NEVER,    // compare op
298                 0u,                                             // compare mask
299                 0u,                                             // write mask
300                 0u);                                    // reference
301
302         const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
303         {
304                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
305                 DE_NULL,                                                                                                        // const void*                                                          pNext;
306                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
307                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
308                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
309                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
310                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
311                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
312                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
313                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
314                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
315                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
316         };
317
318         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
319         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
320         {
321                 m_blendEnable,                                          // VkBool32                                     blendEnable;
322                 VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
323                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
324                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
325                 VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
326                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
327                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
328                 colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
329         };
330
331         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
332         {
333                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
334                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
335                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
336                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
337                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
338                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
339                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
340                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
341         };
342
343         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
344         {
345                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
346                 DE_NULL,                                                                                                                                // const void*                                                                          pNext;
347                 (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
348                 static_cast<deUint32>(m_shaderStages.size()),                                                   // deUint32                                                                                     stageCount;
349                 &m_shaderStages[0],                                                                                                             // const VkPipelineShaderStageCreateInfo*                       pStages;
350                 &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
351                 &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
352                 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*             pTessellationState;
353                 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),               // const VkPipelineViewportStateCreateInfo*                     pViewportState;
354                 &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
355                 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
356                 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),   // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
357                 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),             // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
358                 DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
359                 pipelineLayout,                                                                                                                 // VkPipelineLayout                                                                     layout;
360                 renderPass,                                                                                                                             // VkRenderPass                                                                         renderPass;
361                 0u,                                                                                                                                             // deUint32                                                                                     subpass;
362                 DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
363                 0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
364         };
365
366         {
367                 const vk::Unique<vk::VkPipelineCache>   pipelineCache   (pipelineCacheData.createPipelineCache(vk, device));
368                 vk::Move<vk::VkPipeline>                                pipeline                (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
369
370                 // Refresh data from cache
371                 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
372
373                 return pipeline;
374         }
375 }
376
377 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
378 {
379         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
380
381         if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
382                 throw tcu::NotSupportedError("Tessellation shader not supported");
383
384         if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
385                 throw tcu::NotSupportedError("Geometry shader not supported");
386
387         if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
388                 throw tcu::NotSupportedError("Double-precision floats not supported");
389
390         if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
391                 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
392
393         if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
394                 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
395
396         if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
397                 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
398 }
399
400 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
401 {
402         const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
403         if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
404                 throw tcu::NotSupportedError("Storage image format not supported");
405 }
406
407 std::string getResourceName (const ResourceDescription& resource)
408 {
409         std::ostringstream str;
410
411         if (resource.type == RESOURCE_TYPE_BUFFER)
412                 str << "buffer_" << resource.size.x();
413         else if (resource.type == RESOURCE_TYPE_IMAGE)
414         {
415                 str << "image_" << resource.size.x()
416                                                 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
417                                                 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
418                         << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
419         }
420         else if (isIndirectBuffer(resource.type))
421                 str << "indirect_buffer";
422         else
423                 DE_ASSERT(0);
424
425         return str.str();
426 }
427
428 bool isIndirectBuffer (const ResourceType type)
429 {
430         switch (type)
431         {
432                 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
433                 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
434                 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
435                         return true;
436
437                 default:
438                         return false;
439         }
440 }
441
442 PipelineCacheData::PipelineCacheData (void)
443 {
444 }
445
446 PipelineCacheData::~PipelineCacheData (void)
447 {
448 }
449
450 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
451 {
452         const de::ScopedLock                                            dataLock        (m_lock);
453         const struct vk::VkPipelineCacheCreateInfo      params  =
454         {
455                 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
456                 DE_NULL,
457                 (vk::VkPipelineCacheCreateFlags)0,
458                 (deUintptr)m_data.size(),
459                 (m_data.empty() ? DE_NULL : &m_data[0])
460         };
461
462         return vk::createPipelineCache(vk, device, &params);
463 }
464
465 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
466 {
467         const de::ScopedLock            dataLock                (m_lock);
468         deUintptr                                       dataSize                = 0;
469
470         VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
471
472         m_data.resize(dataSize);
473
474         if (dataSize > 0)
475                 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
476 }
477
478 } // synchronization
479 } // vkt