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