Merge vk-gl-cts/opengl-es-cts-3.2.4 into vk-gl-cts/opengl-es-cts-3.2.5
[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 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize                     bufferSize,
36                                                                                  const VkBufferUsageFlags       usage)
37 {
38         const VkBufferCreateInfo bufferCreateInfo =
39         {
40                 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,   // VkStructureType              sType;
41                 DE_NULL,                                                                // const void*                  pNext;
42                 (VkBufferCreateFlags)0,                                 // VkBufferCreateFlags  flags;
43                 bufferSize,                                                             // VkDeviceSize                 size;
44                 usage,                                                                  // VkBufferUsageFlags   usage;
45                 VK_SHARING_MODE_EXCLUSIVE,                              // VkSharingMode                sharingMode;
46                 0u,                                                                             // deUint32                             queueFamilyIndexCount;
47                 DE_NULL,                                                                // const deUint32*              pQueueFamilyIndices;
48         };
49         return bufferCreateInfo;
50 }
51
52 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags  srcAccessMask,
53                                                                    const VkAccessFlags  dstAccessMask)
54 {
55         const VkMemoryBarrier barrier =
56         {
57                 VK_STRUCTURE_TYPE_MEMORY_BARRIER,       // VkStructureType    sType;
58                 DE_NULL,                                                        // const void*        pNext;
59                 srcAccessMask,                                          // VkAccessFlags      srcAccessMask;
60                 dstAccessMask,                                          // VkAccessFlags      dstAccessMask;
61         };
62         return barrier;
63 }
64
65 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags      srcAccessMask,
66                                                                                            const VkAccessFlags  dstAccessMask,
67                                                                                            const VkBuffer               buffer,
68                                                                                            const VkDeviceSize   offset,
69                                                                                            const VkDeviceSize   bufferSizeBytes)
70 {
71         const VkBufferMemoryBarrier barrier =
72         {
73                 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,        // VkStructureType      sType;
74                 DE_NULL,                                                                        // const void*          pNext;
75                 srcAccessMask,                                                          // VkAccessFlags        srcAccessMask;
76                 dstAccessMask,                                                          // VkAccessFlags        dstAccessMask;
77                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     srcQueueFamilyIndex;
78                 VK_QUEUE_FAMILY_IGNORED,                                        // deUint32                     destQueueFamilyIndex;
79                 buffer,                                                                         // VkBuffer                     buffer;
80                 offset,                                                                         // VkDeviceSize         offset;
81                 bufferSizeBytes,                                                        // VkDeviceSize         size;
82         };
83         return barrier;
84 }
85
86 VkImageMemoryBarrier makeImageMemoryBarrier     (const VkAccessFlags                    srcAccessMask,
87                                                                                          const VkAccessFlags                    dstAccessMask,
88                                                                                          const VkImageLayout                    oldLayout,
89                                                                                          const VkImageLayout                    newLayout,
90                                                                                          const VkImage                                  image,
91                                                                                          const VkImageSubresourceRange  subresourceRange)
92 {
93         const VkImageMemoryBarrier barrier =
94         {
95                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
96                 DE_NULL,                                                                                // const void*                          pNext;
97                 srcAccessMask,                                                                  // VkAccessFlags                        outputMask;
98                 dstAccessMask,                                                                  // VkAccessFlags                        inputMask;
99                 oldLayout,                                                                              // VkImageLayout                        oldLayout;
100                 newLayout,                                                                              // VkImageLayout                        newLayout;
101                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
102                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     destQueueFamilyIndex;
103                 image,                                                                                  // VkImage                                      image;
104                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
105         };
106         return barrier;
107 }
108
109 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
110 {
111         const VkCommandBufferAllocateInfo info =
112         {
113                 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,         // VkStructureType              sType;
114                 DE_NULL,                                                                                        // const void*                  pNext;
115                 commandPool,                                                                            // VkCommandPool                commandPool;
116                 VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                        // VkCommandBufferLevel level;
117                 1u,                                                                                                     // deUint32                             commandBufferCount;
118         };
119         return allocateCommandBuffer(vk, device, &info);
120 }
121
122 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface&                 vk,
123                                                                                  const VkDevice                                 device,
124                                                                                  const VkDescriptorPool                 descriptorPool,
125                                                                                  const VkDescriptorSetLayout    setLayout)
126 {
127         const VkDescriptorSetAllocateInfo info =
128         {
129                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,         // VkStructureType                              sType;
130                 DE_NULL,                                                                                        // const void*                                  pNext;
131                 descriptorPool,                                                                         // VkDescriptorPool                             descriptorPool;
132                 1u,                                                                                                     // deUint32                                             descriptorSetCount;
133                 &setLayout,                                                                                     // const VkDescriptorSetLayout* pSetLayouts;
134         };
135         return allocateDescriptorSet(vk, device, &info);
136 }
137
138 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface&               vk,
139                                                                                    const VkDevice                               device,
140                                                                                    const VkDescriptorSetLayout  descriptorSetLayout)
141 {
142         const VkPipelineLayoutCreateInfo info =
143         {
144                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
145                 DE_NULL,                                                                                        // const void*                                  pNext;
146                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
147                 1u,                                                                                                     // deUint32                                             setLayoutCount;
148                 &descriptorSetLayout,                                                           // const VkDescriptorSetLayout* pSetLayouts;
149                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
150                 DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
151         };
152         return createPipelineLayout(vk, device, &info);
153 }
154
155 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface&             vk,
156                                                                                                                          const VkDevice                         device)
157 {
158         const VkPipelineLayoutCreateInfo info =
159         {
160                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                              sType;
161                 DE_NULL,                                                                                        // const void*                                  pNext;
162                 (VkPipelineLayoutCreateFlags)0,                                         // VkPipelineLayoutCreateFlags  flags;
163                 0u,                                                                                                     // deUint32                                             setLayoutCount;
164                 DE_NULL,                                                                                        // const VkDescriptorSetLayout* pSetLayouts;
165                 0u,                                                                                                     // deUint32                                             pushConstantRangeCount;
166                 DE_NULL,                                                                                        // const VkPushConstantRange*   pPushConstantRanges;
167         };
168         return createPipelineLayout(vk, device, &info);
169 }
170
171 Move<VkPipeline> makeComputePipeline (const DeviceInterface&            vk,
172                                                                           const VkDevice                                device,
173                                                                           const VkPipelineLayout                pipelineLayout,
174                                                                           const VkShaderModule                  shaderModule,
175                                                                           const VkSpecializationInfo*   specInfo,
176                                                                           PipelineCacheData&                    pipelineCacheData)
177 {
178         const VkPipelineShaderStageCreateInfo shaderStageInfo =
179         {
180                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                      sType;
181                 DE_NULL,                                                                                                // const void*                                          pNext;
182                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags     flags;
183                 VK_SHADER_STAGE_COMPUTE_BIT,                                                    // VkShaderStageFlagBits                        stage;
184                 shaderModule,                                                                                   // VkShaderModule                                       module;
185                 "main",                                                                                                 // const char*                                          pName;
186                 specInfo,                                                                                               // const VkSpecializationInfo*          pSpecializationInfo;
187         };
188         const VkComputePipelineCreateInfo pipelineInfo =
189         {
190                 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,         // VkStructureType                                      sType;
191                 DE_NULL,                                                                                        // const void*                                          pNext;
192                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                        flags;
193                 shaderStageInfo,                                                                        // VkPipelineShaderStageCreateInfo      stage;
194                 pipelineLayout,                                                                         // VkPipelineLayout                                     layout;
195                 DE_NULL,                                                                                        // VkPipeline                                           basePipelineHandle;
196                 0,                                                                                                      // deInt32                                                      basePipelineIndex;
197         };
198
199         {
200                 const vk::Unique<vk::VkPipelineCache>   pipelineCache   (pipelineCacheData.createPipelineCache(vk, device));
201                 vk::Move<vk::VkPipeline>                                pipeline                (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
202
203                 // Refresh data from cache
204                 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
205
206                 return pipeline;
207         }
208 }
209
210 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
211 {
212         const VkImageCreateInfo imageInfo =
213         {
214                 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,            // VkStructureType          sType;
215                 DE_NULL,                                                                        // const void*              pNext;
216                 (VkImageCreateFlags)0,                                          // VkImageCreateFlags       flags;
217                 imageType,                                                                      // VkImageType              imageType;
218                 format,                                                                         // VkFormat                 format;
219                 extent,                                                                         // VkExtent3D               extent;
220                 1u,                                                                                     // uint32_t                 mipLevels;
221                 1u,                                                                                     // uint32_t                 arrayLayers;
222                 VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits    samples;
223                 VK_IMAGE_TILING_OPTIMAL,                                        // VkImageTiling            tiling;
224                 usage,                                                                          // VkImageUsageFlags        usage;
225                 VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode            sharingMode;
226                 0u,                                                                                     // uint32_t                 queueFamilyIndexCount;
227                 DE_NULL,                                                                        // const uint32_t*          pQueueFamilyIndices;
228                 VK_IMAGE_LAYOUT_UNDEFINED,                                      // VkImageLayout            initialLayout;
229         };
230         return imageInfo;
231 }
232
233 Move<VkImageView> makeImageView (const DeviceInterface&                 vk,
234                                                                  const VkDevice                                 device,
235                                                                  const VkImage                                  image,
236                                                                  const VkImageViewType                  viewType,
237                                                                  const VkFormat                                 format,
238                                                                  const VkImageSubresourceRange  subresourceRange)
239 {
240         const VkImageViewCreateInfo imageViewParams =
241         {
242                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
243                 DE_NULL,                                                                                // const void*                          pNext;
244                 (VkImageViewCreateFlags)0,                                              // VkImageViewCreateFlags       flags;
245                 image,                                                                                  // VkImage                                      image;
246                 viewType,                                                                               // VkImageViewType                      viewType;
247                 format,                                                                                 // VkFormat                                     format;
248                 makeComponentMappingRGBA(),                                             // VkComponentMapping           components;
249                 subresourceRange,                                                               // VkImageSubresourceRange      subresourceRange;
250         };
251         return createImageView(vk, device, &imageViewParams);
252 }
253
254 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers   subresourceLayers,
255                                                                            const VkExtent3D                                     extent)
256 {
257         const VkBufferImageCopy copyParams =
258         {
259                 0ull,                                                                           //      VkDeviceSize                            bufferOffset;
260                 0u,                                                                                     //      deUint32                                        bufferRowLength;
261                 0u,                                                                                     //      deUint32                                        bufferImageHeight;
262                 subresourceLayers,                                                      //      VkImageSubresourceLayers        imageSubresource;
263                 makeOffset3D(0, 0, 0),                                          //      VkOffset3D                                      imageOffset;
264                 extent,                                                                         //      VkExtent3D                                      imageExtent;
265         };
266         return copyParams;
267 }
268
269 void beginRenderPassWithRasterizationDisabled (const DeviceInterface&   vk,
270                                                                                            const VkCommandBuffer        commandBuffer,
271                                                                                            const VkRenderPass           renderPass,
272                                                                                            const VkFramebuffer          framebuffer)
273 {
274         const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
275
276         beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
277 }
278
279 Move<VkRenderPass> makeRenderPass (const DeviceInterface&       vk,
280                                                                    const VkDevice                       device,
281                                                                    const VkFormat                       colorFormat)
282 {
283         const VkAttachmentDescription colorAttachmentDescription =
284         {
285                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
286                 colorFormat,                                                                            // VkFormat                                                     format;
287                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
288                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
289                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
290                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
291                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
292                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
293                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
294         };
295
296         const VkAttachmentReference colorAttachmentReference =
297         {
298                 0u,                                                                                                     // deUint32                     attachment;
299                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
300         };
301
302         const VkAttachmentReference depthAttachmentReference =
303         {
304                 VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
305                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
306         };
307
308         const VkSubpassDescription subpassDescription =
309         {
310                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
311                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
312                 0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
313                 DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
314                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
315                 &colorAttachmentReference,                                                      // const VkAttachmentReference*         pColorAttachments;
316                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
317                 &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
318                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
319                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
320         };
321
322         const VkRenderPassCreateInfo renderPassInfo =
323         {
324                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
325                 DE_NULL,                                                                                        // const void*                                          pNext;
326                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
327                 1u,                                                                                                     // deUint32                                                     attachmentCount;
328                 &colorAttachmentDescription,                                            // const VkAttachmentDescription*       pAttachments;
329                 1u,                                                                                                     // deUint32                                                     subpassCount;
330                 &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
331                 0u,                                                                                                     // deUint32                                                     dependencyCount;
332                 DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
333         };
334
335         return createRenderPass(vk, device, &renderPassInfo);
336 }
337
338 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface&             vk,
339                                                                          const VkDevice                         device,
340                                                                          const VkRenderPass                     renderPass,
341                                                                          const VkImageView                      colorAttachment,
342                                                                          const deUint32                         width,
343                                                                          const deUint32                         height,
344                                                                          const deUint32                         layers)
345 {
346         const VkFramebufferCreateInfo framebufferInfo = {
347                 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,              // VkStructureType                             sType;
348                 DE_NULL,                                                                                // const void*                                 pNext;
349                 (VkFramebufferCreateFlags)0,                                    // VkFramebufferCreateFlags                    flags;
350                 renderPass,                                                                             // VkRenderPass                                renderPass;
351                 1u,                                                                                             // uint32_t                                    attachmentCount;
352                 &colorAttachment,                                                               // const VkImageView*                          pAttachments;
353                 width,                                                                                  // uint32_t                                    width;
354                 height,                                                                                 // uint32_t                                    height;
355                 layers,                                                                                 // uint32_t                                    layers;
356         };
357
358         return createFramebuffer(vk, device, &framebufferInfo);
359 }
360
361 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface&                     vk,
362                                                                                                                          const VkDevice                                 device,
363                                                                                                                          const VkShaderStageFlagBits    stage,
364                                                                                                                          const ProgramBinary&                   binary,
365                                                                                                                          const VkSpecializationInfo*    specInfo)
366 {
367         VkShaderModule module;
368         switch (stage)
369         {
370                 case (VK_SHADER_STAGE_VERTEX_BIT):
371                         DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
372                         m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
373                         module = *m_vertexShaderModule;
374                         break;
375
376                 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
377                         DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
378                         m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
379                         module = *m_tessControlShaderModule;
380                         break;
381
382                 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
383                         DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
384                         m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
385                         module = *m_tessEvaluationShaderModule;
386                         break;
387
388                 case (VK_SHADER_STAGE_GEOMETRY_BIT):
389                         DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
390                         m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
391                         module = *m_geometryShaderModule;
392                         break;
393
394                 case (VK_SHADER_STAGE_FRAGMENT_BIT):
395                         DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
396                         m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
397                         module = *m_fragmentShaderModule;
398                         break;
399
400                 default:
401                         DE_FATAL("Invalid shader stage");
402                         return *this;
403         }
404
405         const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
406         {
407                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,    // VkStructureType                                              sType;
408                 DE_NULL,                                                                                                // const void*                                                  pNext;
409                 (VkPipelineShaderStageCreateFlags)0,                                    // VkPipelineShaderStageCreateFlags             flags;
410                 stage,                                                                                                  // VkShaderStageFlagBits                                stage;
411                 module,                                                                                                 // VkShaderModule                                               module;
412                 "main",                                                                                                 // const char*                                                  pName;
413                 specInfo,                                                                                               // const VkSpecializationInfo*                  pSpecializationInfo;
414         };
415
416         m_shaderStageFlags |= stage;
417         m_shaderStages.push_back(pipelineShaderStageInfo);
418
419         return *this;
420 }
421
422 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
423 {
424         const VkVertexInputBindingDescription bindingDesc =
425         {
426                 0u,                                                                     // uint32_t                             binding;
427                 stride,                                                         // uint32_t                             stride;
428                 VK_VERTEX_INPUT_RATE_VERTEX,            // VkVertexInputRate    inputRate;
429         };
430         const VkVertexInputAttributeDescription attributeDesc =
431         {
432                 0u,                                                                     // uint32_t                     location;
433                 0u,                                                                     // uint32_t                     binding;
434                 vertexFormat,                                           // VkFormat                     format;
435                 0u,                                                                     // uint32_t                     offset;
436         };
437
438         m_vertexInputBindings.clear();
439         m_vertexInputBindings.push_back(bindingDesc);
440
441         m_vertexInputAttributes.clear();
442         m_vertexInputAttributes.push_back(attributeDesc);
443
444         return *this;
445 }
446
447 template<typename T>
448 inline const T* dataPointer (const std::vector<T>& vec)
449 {
450         return (vec.size() != 0 ? &vec[0] : DE_NULL);
451 }
452
453 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
454                                                                                                  const VkDevice                 device,
455                                                                                                  const VkPipelineLayout pipelineLayout,
456                                                                                                  const VkRenderPass             renderPass,
457                                                                                                  PipelineCacheData&             pipelineCacheData)
458 {
459         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
460         {
461                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
462                 DE_NULL,                                                                                                                // const void*                                 pNext;
463                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
464                 static_cast<deUint32>(m_vertexInputBindings.size()),                    // uint32_t                                    vertexBindingDescriptionCount;
465                 dataPointer(m_vertexInputBindings),                                                             // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
466                 static_cast<deUint32>(m_vertexInputAttributes.size()),                  // uint32_t                                    vertexAttributeDescriptionCount;
467                 dataPointer(m_vertexInputAttributes),                                                   // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
468         };
469
470         const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
471                                                                                                                                                                                                                  : m_primitiveTopology;
472         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
473         {
474                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
475                 DE_NULL,                                                                                                                // const void*                                 pNext;
476                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
477                 topology,                                                                                                               // VkPrimitiveTopology                         topology;
478                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
479         };
480
481         const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
482         {
483                 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,              // VkStructureType                             sType;
484                 DE_NULL,                                                                                                                // const void*                                 pNext;
485                 (VkPipelineTessellationStateCreateFlags)0,                                              // VkPipelineTessellationStateCreateFlags      flags;
486                 m_patchControlPoints,                                                                                   // uint32_t                                    patchControlPoints;
487         };
488
489         const VkViewport viewport = makeViewport(
490                 0.0f, 0.0f,
491                 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
492                 0.0f, 1.0f);
493
494         const VkRect2D scissor = {
495                 makeOffset2D(0, 0),
496                 makeExtent2D(m_renderSize.x(), m_renderSize.y()),
497         };
498
499         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
500         {
501                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
502                 DE_NULL,                                                                                                // const void*                                 pNext;
503                 (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
504                 1u,                                                                                                             // uint32_t                                    viewportCount;
505                 &viewport,                                                                                              // const VkViewport*                           pViewports;
506                 1u,                                                                                                             // uint32_t                                    scissorCount;
507                 &scissor,                                                                                               // const VkRect2D*                             pScissors;
508         };
509
510         const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
511         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
512         {
513                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
514                 DE_NULL,                                                                                                                // const void*                              pNext;
515                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
516                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
517                 isRasterizationDisabled,                                                                                // VkBool32                                 rasterizerDiscardEnable;
518                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
519                 m_cullModeFlags,                                                                                                // VkCullModeFlags                                                      cullMode;
520                 m_frontFace,                                                                                                    // VkFrontFace                                                          frontFace;
521                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
522                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
523                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
524                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
525                 1.0f,                                                                                                                   // float                                                                        lineWidth;
526         };
527
528         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
529         {
530                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
531                 DE_NULL,                                                                                                        // const void*                                                          pNext;
532                 (VkPipelineMultisampleStateCreateFlags)0,                                       // VkPipelineMultisampleStateCreateFlags        flags;
533                 VK_SAMPLE_COUNT_1_BIT,                                                                          // VkSampleCountFlagBits                                        rasterizationSamples;
534                 VK_FALSE,                                                                                                       // VkBool32                                                                     sampleShadingEnable;
535                 0.0f,                                                                                                           // float                                                                        minSampleShading;
536                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
537                 VK_FALSE,                                                                                                       // VkBool32                                                                     alphaToCoverageEnable;
538                 VK_FALSE                                                                                                        // VkBool32                                                                     alphaToOneEnable;
539         };
540
541         const VkStencilOpState stencilOpState = makeStencilOpState(
542                 VK_STENCIL_OP_KEEP,             // stencil fail
543                 VK_STENCIL_OP_KEEP,             // depth & stencil pass
544                 VK_STENCIL_OP_KEEP,             // depth only fail
545                 VK_COMPARE_OP_NEVER,    // compare op
546                 0u,                                             // compare mask
547                 0u,                                             // write mask
548                 0u);                                    // reference
549
550         const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
551         {
552                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
553                 DE_NULL,                                                                                                        // const void*                                                          pNext;
554                 (VkPipelineDepthStencilStateCreateFlags)0,                                      // VkPipelineDepthStencilStateCreateFlags       flags;
555                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthTestEnable;
556                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthWriteEnable;
557                 VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
558                 VK_FALSE,                                                                                                       // VkBool32                                                                     depthBoundsTestEnable;
559                 VK_FALSE,                                                                                                       // VkBool32                                                                     stencilTestEnable;
560                 stencilOpState,                                                                                         // VkStencilOpState                                                     front;
561                 stencilOpState,                                                                                         // VkStencilOpState                                                     back;
562                 0.0f,                                                                                                           // float                                                                        minDepthBounds;
563                 1.0f,                                                                                                           // float                                                                        maxDepthBounds;
564         };
565
566         const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
567         const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
568         {
569                 m_blendEnable,                                          // VkBool32                                     blendEnable;
570                 VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcColorBlendFactor;
571                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstColorBlendFactor;
572                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            colorBlendOp;
573                 VK_BLEND_FACTOR_SRC_ALPHA,                      // VkBlendFactor                        srcAlphaBlendFactor;
574                 VK_BLEND_FACTOR_ONE,                            // VkBlendFactor                        dstAlphaBlendFactor;
575                 VK_BLEND_OP_ADD,                                        // VkBlendOp                            alphaBlendOp;
576                 colorComponentsAll,                                     // VkColorComponentFlags        colorWriteMask;
577         };
578
579         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
580         {
581                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
582                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
583                 (VkPipelineColorBlendStateCreateFlags)0,                                        // VkPipelineColorBlendStateCreateFlags                 flags;
584                 VK_FALSE,                                                                                                       // VkBool32                                                                             logicOpEnable;
585                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
586                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
587                 &pipelineColorBlendAttachmentState,                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
588                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
589         };
590
591         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
592         {
593                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
594                 DE_NULL,                                                                                                                                // const void*                                                                          pNext;
595                 (VkPipelineCreateFlags)0,                                                                                               // VkPipelineCreateFlags                                                        flags;
596                 static_cast<deUint32>(m_shaderStages.size()),                                                   // deUint32                                                                                     stageCount;
597                 &m_shaderStages[0],                                                                                                             // const VkPipelineShaderStageCreateInfo*                       pStages;
598                 &vertexInputStateInfo,                                                                                                  // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
599                 &pipelineInputAssemblyStateInfo,                                                                                // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
600                 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo*             pTessellationState;
601                 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo),               // const VkPipelineViewportStateCreateInfo*                     pViewportState;
602                 &pipelineRasterizationStateInfo,                                                                                // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
603                 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
604                 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),   // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
605                 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),             // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
606                 DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
607                 pipelineLayout,                                                                                                                 // VkPipelineLayout                                                                     layout;
608                 renderPass,                                                                                                                             // VkRenderPass                                                                         renderPass;
609                 0u,                                                                                                                                             // deUint32                                                                                     subpass;
610                 DE_NULL,                                                                                                                                // VkPipeline                                                                           basePipelineHandle;
611                 0,                                                                                                                                              // deInt32                                                                                      basePipelineIndex;
612         };
613
614         {
615                 const vk::Unique<vk::VkPipelineCache>   pipelineCache   (pipelineCacheData.createPipelineCache(vk, device));
616                 vk::Move<vk::VkPipeline>                                pipeline                (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
617
618                 // Refresh data from cache
619                 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
620
621                 return pipeline;
622         }
623 }
624
625 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
626 {
627         const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
628
629         if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
630                 throw tcu::NotSupportedError("Tessellation shader not supported");
631
632         if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
633                 throw tcu::NotSupportedError("Geometry shader not supported");
634
635         if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
636                 throw tcu::NotSupportedError("Double-precision floats not supported");
637
638         if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
639                 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
640
641         if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
642                 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
643
644         if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
645                 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
646
647         if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats)
648                 throw tcu::NotSupportedError("Storage image extended formats not supported");
649 }
650
651 std::string getResourceName (const ResourceDescription& resource)
652 {
653         std::ostringstream str;
654
655         if (resource.type == RESOURCE_TYPE_BUFFER)
656                 str << "buffer_" << resource.size.x();
657         else if (resource.type == RESOURCE_TYPE_IMAGE)
658         {
659                 str << "image_" << resource.size.x()
660                                                 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
661                                                 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
662                         << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
663         }
664         else if (isIndirectBuffer(resource.type))
665                 str << "indirect_buffer";
666         else
667                 DE_ASSERT(0);
668
669         return str.str();
670 }
671
672 bool isIndirectBuffer (const ResourceType type)
673 {
674         switch (type)
675         {
676                 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
677                 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
678                 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
679                         return true;
680
681                 default:
682                         return false;
683         }
684 }
685
686 PipelineCacheData::PipelineCacheData (void)
687 {
688 }
689
690 PipelineCacheData::~PipelineCacheData (void)
691 {
692 }
693
694 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
695 {
696         const de::ScopedLock                                            dataLock        (m_lock);
697         const struct vk::VkPipelineCacheCreateInfo      params  =
698         {
699                 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
700                 DE_NULL,
701                 (vk::VkPipelineCacheCreateFlags)0,
702                 (deUintptr)m_data.size(),
703                 (m_data.empty() ? DE_NULL : &m_data[0])
704         };
705
706         return vk::createPipelineCache(vk, device, &params);
707 }
708
709 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
710 {
711         const de::ScopedLock            dataLock                (m_lock);
712         deUintptr                                       dataSize                = 0;
713
714         VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
715
716         m_data.resize(dataSize);
717
718         if (dataSize > 0)
719                 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
720 }
721
722 } // synchronization
723 } // vkt