Added test to stress semaphore chains
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / synchronization / vktSynchronizationInternallySynchronizedObjectsTests.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 internally synchronized objects tests
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationInternallySynchronizedObjectsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktSynchronizationUtil.hpp"
27
28 #include "vkRef.hpp"
29 #include "tcuDefs.hpp"
30 #include "vkTypeUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkBuilderUtil.hpp"
33 #include "vkImageUtil.hpp"
34
35 #include "tcuResultCollector.hpp"
36
37 #include "deThread.hpp"
38 #include "deMutex.hpp"
39 #include "deSharedPtr.hpp"
40
41
42 #include <limits>
43 #include <iterator>
44
45 namespace vkt
46 {
47 namespace synchronization
48 {
49 namespace
50 {
51 using namespace vk;
52
53 using std::vector;
54 using std::string;
55 using std::map;
56 using std::exception;
57 using std::ostringstream;
58
59 using tcu::TestStatus;
60 using tcu::TestContext;
61 using tcu::ResultCollector;
62 using tcu::TestException;
63
64 using de::UniquePtr;
65 using de::MovePtr;
66 using de::SharedPtr;
67 using de::Mutex;
68 using de::Thread;
69 using de::clamp;
70
71 enum {EXECUTION_PER_THREAD = 100, BUFFER_ELEMENT_COUNT = 16, BUFFER_SIZE = BUFFER_ELEMENT_COUNT*4 };
72
73 class MultiQueues
74 {
75         typedef struct QueueType
76         {
77                 vector<VkQueue> queues;
78                 vector<bool>    available;
79         } Queues;
80
81 public:
82
83         inline void             addQueueFamilyIndex             (const deUint32& queueFamilyIndex, const deUint32& count)
84         {
85                 Queues temp;
86                 vector<bool>::iterator it;
87                 it = temp.available.begin();
88                 temp.available.insert(it, count, false);
89
90                 temp.queues.resize(count);
91                 m_queues[queueFamilyIndex] = temp;
92         }
93
94         const deUint32& getQueueFamilyIndex             (const int index)
95         {
96                 map<deUint32,Queues>::iterator it = m_queues.begin();
97                 advance (it, index);
98                 return it->first;
99         }
100
101         inline size_t   countQueueFamilyIndex   (void)
102         {
103                 return m_queues.size();
104         }
105
106         Queues &                getQueues                               (const int index)
107         {
108                 map<deUint32,Queues>::iterator it = m_queues.begin();
109                 advance (it, index);
110                 return it->second;
111         }
112
113         bool                    getFreeQueue                    (deUint32& returnQueueFamilyIndex, VkQueue& returnQueues, int& returnQueueIndex)
114         {
115                 for (int queueFamilyIndexNdx = 0 ; queueFamilyIndexNdx < static_cast<int>(m_queues.size()); ++queueFamilyIndexNdx)
116                 {
117                         Queues& queue = m_queues[getQueueFamilyIndex(queueFamilyIndexNdx)];
118                         for (int queueNdx = 0; queueNdx < static_cast<int>(queue.queues.size()); ++queueNdx)
119                         {
120                                 m_mutex.lock();
121                                 if (queue.available[queueNdx])
122                                 {
123                                         queue.available[queueNdx]       = false;
124                                         returnQueueFamilyIndex          = getQueueFamilyIndex(queueFamilyIndexNdx);
125                                         returnQueues                            = queue.queues[queueNdx];
126                                         returnQueueIndex                        = queueNdx;
127                                         m_mutex.unlock();
128                                         return true;
129                                 }
130                                 m_mutex.unlock();
131                         }
132                 }
133                 return false;
134         }
135
136         void                    releaseQueue                    (const deUint32& queueFamilyIndex, const int& queueIndex)
137         {
138                 m_mutex.lock();
139                 m_queues[queueFamilyIndex].available[queueIndex] = true;
140                 m_mutex.unlock();
141         }
142
143         inline void             setDevice                               (Move<VkDevice> device)
144         {
145                 m_logicalDevice = device;
146         }
147
148         inline VkDevice getDevice                               (void)
149         {
150                 return *m_logicalDevice;
151         }
152
153         MovePtr<Allocator>              m_allocator;
154 protected:
155         Move<VkDevice>                  m_logicalDevice;
156         map<deUint32,Queues>    m_queues;
157         Mutex                                   m_mutex;
158
159 };
160
161 MovePtr<Allocator> createAllocator (const Context& context, const VkDevice& device)
162 {
163         const DeviceInterface&                                  deviceInterface                 = context.getDeviceInterface();
164         const InstanceInterface&                                instance                                = context.getInstanceInterface();
165         const VkPhysicalDevice                                  physicalDevice                  = context.getPhysicalDevice();
166         const VkPhysicalDeviceMemoryProperties  deviceMemoryProperties  = getPhysicalDeviceMemoryProperties(instance, physicalDevice);
167
168         // Create memory allocator for device
169         return MovePtr<Allocator> (new SimpleAllocator(deviceInterface, device, deviceMemoryProperties));
170 }
171
172 bool checkQueueFlags (const VkQueueFlags& availableFlag, const VkQueueFlags& neededFlag)
173 {
174         if (VK_QUEUE_TRANSFER_BIT == neededFlag)
175         {
176                 if ( (availableFlag & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT ||
177                          (availableFlag & VK_QUEUE_COMPUTE_BIT)  == VK_QUEUE_COMPUTE_BIT  ||
178                          (availableFlag & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT
179                    )
180                         return true;
181         }
182         else if ((availableFlag & neededFlag) == neededFlag)
183         {
184                 return true;
185         }
186         return false;
187 }
188
189 MovePtr<MultiQueues> createQueues (const Context& context, const VkQueueFlags& queueFlag)
190 {
191         const DeviceInterface&                                  vk                                              = context.getDeviceInterface();
192         const InstanceInterface&                                instance                                = context.getInstanceInterface();
193         const VkPhysicalDevice                                  physicalDevice                  = context.getPhysicalDevice();
194         MovePtr<MultiQueues>                                    moveQueues                              (new MultiQueues());
195         MultiQueues&                                                    queues                                  = *moveQueues;
196         VkDeviceCreateInfo                                              deviceInfo;
197         VkPhysicalDeviceFeatures                                deviceFeatures;
198         vector<VkQueueFamilyProperties>                 queueFamilyProperties;
199         vector<float>                                                   queuePriorities;
200         vector<VkDeviceQueueCreateInfo>                 queueInfos;
201
202         queueFamilyProperties = getPhysicalDeviceQueueFamilyProperties(instance, physicalDevice);
203
204         for (deUint32 queuePropertiesNdx = 0; queuePropertiesNdx < queueFamilyProperties.size(); ++queuePropertiesNdx)
205         {
206                 if (checkQueueFlags(queueFamilyProperties[queuePropertiesNdx].queueFlags, queueFlag))
207                 {
208                         queues.addQueueFamilyIndex(queuePropertiesNdx, queueFamilyProperties[queuePropertiesNdx].queueCount);
209                 }
210         }
211
212         if (queues.countQueueFamilyIndex() == 0)
213         {
214                 TCU_THROW(NotSupportedError, "Queue not found");
215         }
216
217         {
218                 vector<float>::iterator it                              = queuePriorities.begin();
219                 unsigned int                    maxQueueCount   = 0;
220                 for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
221                 {
222                         if (queues.getQueues(queueFamilyIndexNdx).queues.size() > maxQueueCount)
223                                 maxQueueCount = static_cast<unsigned int>(queues.getQueues(queueFamilyIndexNdx).queues.size());
224                 }
225                 queuePriorities.insert(it, maxQueueCount, 1.0);
226         }
227
228         for (int queueFamilyIndexNdx = 0; queueFamilyIndexNdx < static_cast<int>(queues.countQueueFamilyIndex()); ++queueFamilyIndexNdx)
229         {
230                 VkDeviceQueueCreateInfo queueInfo;
231                 const deUint32                  queueCount      = static_cast<deUint32>(queues.getQueues(queueFamilyIndexNdx).queues.size());
232
233                 deMemset(&queueInfo, 0, sizeof(queueInfo));
234
235                 queueInfo.sType                         = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
236                 queueInfo.pNext                         = DE_NULL;
237                 queueInfo.flags                         = (VkDeviceQueueCreateFlags)0u;
238                 queueInfo.queueFamilyIndex      = queues.getQueueFamilyIndex(queueFamilyIndexNdx);
239                 queueInfo.queueCount            = queueCount;
240                 queueInfo.pQueuePriorities      = &queuePriorities[0];
241
242                 queueInfos.push_back(queueInfo);
243         }
244
245         deMemset(&deviceInfo, 0, sizeof(deviceInfo));
246         instance.getPhysicalDeviceFeatures(physicalDevice, &deviceFeatures);
247
248         deviceInfo.sType                                        = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
249         deviceInfo.pNext                                        = DE_NULL;
250         deviceInfo.enabledExtensionCount        = 0u;
251         deviceInfo.ppEnabledExtensionNames      = DE_NULL;
252         deviceInfo.enabledLayerCount            = 0u;
253         deviceInfo.ppEnabledLayerNames          = DE_NULL;
254         deviceInfo.pEnabledFeatures                     = &deviceFeatures;
255         deviceInfo.queueCreateInfoCount         = static_cast<deUint32>(queues.countQueueFamilyIndex());
256         deviceInfo.pQueueCreateInfos            = &queueInfos[0];
257
258         queues.setDevice(createDevice(instance, physicalDevice, &deviceInfo));
259
260         for (deUint32 queueFamilyIndex = 0; queueFamilyIndex < queues.countQueueFamilyIndex(); ++queueFamilyIndex)
261         {
262                 for (deUint32 queueReqNdx = 0; queueReqNdx < queues.getQueues(queueFamilyIndex).queues.size(); ++queueReqNdx)
263                 {
264                         vk.getDeviceQueue(queues.getDevice(), queues.getQueueFamilyIndex(queueFamilyIndex), queueReqNdx, &queues.getQueues(queueFamilyIndex).queues[queueReqNdx]);
265                         queues.getQueues(queueFamilyIndex).available[queueReqNdx]=true;
266                 }
267         }
268
269         queues.m_allocator = createAllocator(context, queues.getDevice());
270         return moveQueues;
271 }
272
273 Move<VkRenderPass>      createRenderPass (const Context& context, const VkDevice& device, const VkFormat& colorFormat)
274 {
275         const DeviceInterface&                  vk                                                      = context.getDeviceInterface();
276         const VkAttachmentDescription   colorAttachmentDescription      =
277                                                                                                                                 {
278                                                                                                                                         0u,                                                                                     // VkAttachmentDescriptionFlags flags;
279                                                                                                                                         colorFormat,                                                            // VkFormat                                             format;
280                                                                                                                                         VK_SAMPLE_COUNT_1_BIT,                                          // VkSampleCountFlagBits                samples;
281                                                                                                                                         VK_ATTACHMENT_LOAD_OP_CLEAR,                            // VkAttachmentLoadOp                   loadOp;
282                                                                                                                                         VK_ATTACHMENT_STORE_OP_STORE,                           // VkAttachmentStoreOp                  storeOp;
283                                                                                                                                         VK_ATTACHMENT_LOAD_OP_DONT_CARE,                        // VkAttachmentLoadOp                   stencilLoadOp;
284                                                                                                                                         VK_ATTACHMENT_STORE_OP_DONT_CARE,                       // VkAttachmentStoreOp                  stencilStoreOp;
285                                                                                                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                initialLayout;
286                                                                                                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,       // VkImageLayout                                finalLayout;
287                                                                                                                                 };
288         const VkAttachmentReference             colorAttachmentReference        =
289                                                                                                                                 {
290                                                                                                                                         0u,                                                                                     // deUint32                     attachment;
291                                                                                                                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
292                                                                                                                                 };
293         const VkSubpassDescription              subpassDescription                      =
294                                                                                                                                 {
295                                                                                                                                         0u,                                                                     // VkSubpassDescriptionFlags    flags;
296                                                                                                                                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint;
297                                                                                                                                         0u,                                                                     // deUint32                                             inputAttachmentCount;
298                                                                                                                                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments;
299                                                                                                                                         1u,                                                                     // deUint32                                             colorAttachmentCount;
300                                                                                                                                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments;
301                                                                                                                                         DE_NULL,                                                        // const VkAttachmentReference* pResolveAttachments;
302                                                                                                                                         DE_NULL,                                                        // const VkAttachmentReference* pDepthStencilAttachment;
303                                                                                                                                         0u,                                                                     // deUint32                                             preserveAttachmentCount;
304                                                                                                                                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments;
305                                                                                                                                 };
306         const VkRenderPassCreateInfo    renderPassParams                        =
307                                                                                                                                 {
308                                                                                                                                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,      // VkStructureType                                      sType;
309                                                                                                                                         DE_NULL,                                                                        // const void*                                          pNext;
310                                                                                                                                         0u,                                                                                     // VkRenderPassCreateFlags                      flags;
311                                                                                                                                         1u,                                                                                     // deUint32                                                     attachmentCount;
312                                                                                                                                         &colorAttachmentDescription,                            // const VkAttachmentDescription*       pAttachments;
313                                                                                                                                         1u,                                                                                     // deUint32                                                     subpassCount;
314                                                                                                                                         &subpassDescription,                                            // const VkSubpassDescription*          pSubpasses;
315                                                                                                                                         0u,                                                                                     // deUint32                                                     dependencyCount;
316                                                                                                                                         DE_NULL                                                                         // const VkSubpassDependency*           pDependencies;
317                                                                                                                                 };
318         return createRenderPass(vk, device, &renderPassParams);
319 }
320
321 TestStatus executeComputePipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
322                                                                         const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const deUint32& shadersExecutions)
323 {
324         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
325         const VkDevice                                  device                          = queues.getDevice();
326         deUint32                                                queueFamilyIndex;
327         VkQueue                                                 queue;
328         int                                                             queueIndex;
329         while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){}
330
331         {
332                 const Unique<VkDescriptorPool>  descriptorPool          (DescriptorPoolBuilder()
333                                                                                                                                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
334                                                                                                                                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
335                 Buffer                                                  resultBuffer            (vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
336                 const VkBufferMemoryBarrier             bufferBarrier           = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);
337                 const Unique<VkCommandPool>             cmdPool                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
338                 const Unique<VkCommandBuffer>   cmdBuffer                       (makeCommandBuffer(vk, device, *cmdPool));
339
340                 {
341                         const Allocation& alloc = resultBuffer.getAllocation();
342                         deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
343                         flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), BUFFER_SIZE);
344                 }
345
346                 // Start recording commands
347                 beginCommandBuffer(vk, *cmdBuffer);
348
349                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
350
351                 // Create descriptor set
352                 const Unique<VkDescriptorSet> descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout));
353
354                 const VkDescriptorBufferInfo resultDescriptorInfo = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);
355
356                 DescriptorSetUpdateBuilder()
357                         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultDescriptorInfo)
358                         .update(vk, device);
359
360                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
361
362                 // Dispatch indirect compute command
363                 vk.cmdDispatch(*cmdBuffer, shadersExecutions, 1u, 1u);
364
365                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
366                                                                  0, (const VkMemoryBarrier*)DE_NULL,
367                                                                  1, &bufferBarrier,
368                                                                  0, (const VkImageMemoryBarrier*)DE_NULL);
369
370                 // End recording commands
371                 endCommandBuffer(vk, *cmdBuffer);
372
373                 // Wait for command buffer execution finish
374                 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
375                 queues.releaseQueue(queueFamilyIndex, queueIndex);
376
377                 {
378                         const Allocation& resultAlloc = resultBuffer.getAllocation();
379                         invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), BUFFER_SIZE);
380
381                         const deInt32*  ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
382                         for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
383                         {
384                                 if (ptr[ndx] != ndx)
385                                 {
386                                         return TestStatus::fail("The data don't match");
387                                 }
388                         }
389                 }
390                 return TestStatus::pass("Passed");
391         }
392 }
393
394
395 TestStatus executeGraphicPipeline (const Context& context, const VkPipeline& pipeline, const VkPipelineLayout& pipelineLayout,
396                                                                         const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const VkRenderPass& renderPass, const deUint32 shadersExecutions)
397 {
398         const DeviceInterface&                  vk                                      = context.getDeviceInterface();
399         const VkDevice                                  device                          = queues.getDevice();
400         deUint32                                                queueFamilyIndex;
401         VkQueue                                                 queue;
402         int                                                             queueIndex;
403         while(!queues.getFreeQueue(queueFamilyIndex, queue, queueIndex)){}
404
405         {
406                 const Unique<VkDescriptorPool>  descriptorPool                          (DescriptorPoolBuilder()
407                                                                                                                                                 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
408                                                                                                                                                 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u));
409                 Move<VkDescriptorSet>                   descriptorSet                           = makeDescriptorSet(vk, device, *descriptorPool, descriptorSetLayout);
410                 Buffer                                                  resultBuffer                            (vk, device, *queues.m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
411                 const VkBufferMemoryBarrier             bufferBarrier                           = makeBufferMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, BUFFER_SIZE);
412                 const VkFormat                                  colorFormat                                     = VK_FORMAT_R8G8B8A8_UNORM;
413                 const VkExtent3D                                colorImageExtent                        = makeExtent3D(1u, 1u, 1u);
414                 const VkImageSubresourceRange   colorImageSubresourceRange      = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
415                 de::MovePtr<Image>                              colorAttachmentImage            = de::MovePtr<Image>(new Image(vk, device, *queues.m_allocator,
416                                                                                                                                                 makeImageCreateInfo(VK_IMAGE_TYPE_2D, colorImageExtent, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT),
417                                                                                                                                                 MemoryRequirement::Any));
418                 Move<VkImageView>                               colorAttachmentView                     = makeImageView(vk, device, **colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange);
419                 Move<VkFramebuffer>                             framebuffer                                     = makeFramebuffer(vk, device, renderPass, *colorAttachmentView, colorImageExtent.width, colorImageExtent.height, 1u);
420                 const Unique<VkCommandPool>             cmdPool                                         (createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
421                 const Unique<VkCommandBuffer>   cmdBuffer                                       (makeCommandBuffer(vk, device, *cmdPool));
422                 const VkDescriptorBufferInfo    outputBufferDescriptorInfo      = makeDescriptorBufferInfo(*resultBuffer, 0ull, BUFFER_SIZE);
423
424                 DescriptorSetUpdateBuilder()
425                         .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &outputBufferDescriptorInfo)
426                         .update         (vk, device);
427
428                 {
429                         const Allocation& alloc = resultBuffer.getAllocation();
430                         deMemset(alloc.getHostPtr(), 0, BUFFER_SIZE);
431                         flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), BUFFER_SIZE);
432                 }
433
434                 // Start recording commands
435                 beginCommandBuffer(vk, *cmdBuffer);
436                 // Change color attachment image layout
437                 {
438                         const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier(
439                                 (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
440                                 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
441                                 **colorAttachmentImage, colorImageSubresourceRange);
442
443                         vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
444                                 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier);
445                 }
446
447                 {
448                         const VkRect2D  renderArea      =
449                                                                                 {
450                                                                                         makeOffset2D(0, 0),
451                                                                                         makeExtent2D(1, 1),
452                                                                                 };
453                         const tcu::Vec4 clearColor      = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
454                         beginRenderPass(vk, *cmdBuffer, renderPass, *framebuffer, renderArea, clearColor);
455                 }
456
457                 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
458                 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL);
459
460                 vk.cmdDraw(*cmdBuffer, shadersExecutions, 1u, 0u, 0u);
461                 endRenderPass(vk, *cmdBuffer);
462
463                 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0,
464                                                 0, (const VkMemoryBarrier*)DE_NULL,
465                                                 1, &bufferBarrier,
466                                                 0, (const VkImageMemoryBarrier*)DE_NULL);
467
468                 // End recording commands
469                 endCommandBuffer(vk, *cmdBuffer);
470
471                 // Wait for command buffer execution finish
472                 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
473                 queues.releaseQueue(queueFamilyIndex, queueIndex);
474
475                 {
476                         const Allocation& resultAlloc = resultBuffer.getAllocation();
477                         invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), BUFFER_SIZE);
478
479                         const deInt32*  ptr = reinterpret_cast<deInt32*>(resultAlloc.getHostPtr());
480                         for (deInt32 ndx = 0; ndx < BUFFER_ELEMENT_COUNT; ++ndx)
481                         {
482                                 if (ptr[ndx] != ndx)
483                                 {
484                                         return TestStatus::fail("The data don't match");
485                                 }
486                         }
487                 }
488                 return TestStatus::pass("Passed");
489         }
490 }
491
492
493 class ThreadGroupThread : private Thread
494 {
495 public:
496                                                         ThreadGroupThread       (const Context& context, VkPipelineCache pipelineCache, const VkPipelineLayout& pipelineLayout,
497                                                                                                 const VkDescriptorSetLayout& descriptorSetLayout, MultiQueues& queues, const vector<deUint32>& shadersExecutions)
498                                                                 : m_context                             (context)
499                                                                 , m_pipelineCache               (pipelineCache)
500                                                                 , m_pipelineLayout              (pipelineLayout)
501                                                                 , m_descriptorSetLayout (descriptorSetLayout)
502                                                                 , m_queues                              (queues)
503                                                                 , m_shadersExecutions   (shadersExecutions)
504         {
505         }
506
507         virtual                                 ~ThreadGroupThread      (void)
508         {
509         }
510
511         ResultCollector&                getResultCollector      (void)
512         {
513                 return m_resultCollector;
514         }
515
516         using Thread::start;
517         using Thread::join;
518
519 protected:
520         virtual TestStatus              runThread               () = 0;
521         const Context&                                                  m_context;
522         VkPipelineCache                                                 m_pipelineCache;
523         const VkPipelineLayout&                                 m_pipelineLayout;
524         const VkDescriptorSetLayout&                    m_descriptorSetLayout;
525         MultiQueues&                                                    m_queues;
526         const vector<deUint32>&                                 m_shadersExecutions;
527
528 private:
529                                                         ThreadGroupThread       (const ThreadGroupThread&);
530         ThreadGroupThread&              operator=                       (const ThreadGroupThread&);
531
532         void                                    run                                     (void)
533         {
534                 try
535                 {
536                         TestStatus result = runThread();
537                         m_resultCollector.addResult(result.getCode(), result.getDescription());
538                 }
539                 catch (const TestException& e)
540                 {
541                         m_resultCollector.addResult(e.getTestResult(), e.getMessage());
542                 }
543                 catch (const exception& e)
544                 {
545                         m_resultCollector.addResult(QP_TEST_RESULT_FAIL, e.what());
546                 }
547                 catch (...)
548                 {
549                         m_resultCollector.addResult(QP_TEST_RESULT_FAIL, "Exception");
550                 }
551         }
552
553         ResultCollector                                                 m_resultCollector;
554 };
555
556 class ThreadGroup
557 {
558         typedef vector<SharedPtr<ThreadGroupThread> >   ThreadVector;
559 public:
560                                                         ThreadGroup                     (void)
561         {
562         }
563                                                         ~ThreadGroup            (void)
564         {
565         }
566
567         void                                    add                                     (MovePtr<ThreadGroupThread> thread)
568         {
569                 m_threads.push_back(SharedPtr<ThreadGroupThread>(thread.release()));
570         }
571
572         TestStatus                              run                                     (void)
573         {
574                 ResultCollector resultCollector;
575
576                 for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
577                         (*threadIter)->start();
578
579                 for (ThreadVector::iterator threadIter = m_threads.begin(); threadIter != m_threads.end(); ++threadIter)
580                 {
581                         ResultCollector&        threadResult    = (*threadIter)->getResultCollector();
582                         (*threadIter)->join();
583                         resultCollector.addResult(threadResult.getResult(), threadResult.getMessage());
584                 }
585
586                 return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
587         }
588
589 private:
590         ThreadVector                                                    m_threads;
591 };
592
593
594 class CreateComputeThread : public ThreadGroupThread
595 {
596 public:
597                         CreateComputeThread     (const Context& context, VkPipelineCache pipelineCache, vector<VkComputePipelineCreateInfo>& pipelineInfo,
598                                                                 const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
599                                                                 MultiQueues& queues, const vector<deUint32>& shadersExecutions)
600                                 : ThreadGroupThread             (context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
601                                 , m_pipelineInfo                (pipelineInfo)
602         {
603         }
604
605         TestStatus      runThread               (void)
606         {
607                 ResultCollector         resultCollector;
608                 for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
609                 {
610                         const int shaderNdx                                     = executionNdx % (int)m_pipelineInfo.size();
611                         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
612                         const VkDevice                  device          = m_queues.getDevice();
613                         Move<VkPipeline>                pipeline        = createComputePipeline(vk,device,m_pipelineCache, &m_pipelineInfo[shaderNdx]);
614
615                         TestStatus result = executeComputePipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_shadersExecutions[shaderNdx]);
616                         resultCollector.addResult(result.getCode(), result.getDescription());
617                 }
618                 return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
619         }
620 private:
621         vector<VkComputePipelineCreateInfo>&    m_pipelineInfo;
622 };
623
624 class CreateGraphicThread : public ThreadGroupThread
625 {
626 public:
627                         CreateGraphicThread     (const Context& context, VkPipelineCache pipelineCache, vector<VkGraphicsPipelineCreateInfo>& pipelineInfo,
628                                                                 const VkPipelineLayout& pipelineLayout, const VkDescriptorSetLayout& descriptorSetLayout,
629                                                                 MultiQueues& queues, const VkRenderPass& renderPass, const vector<deUint32>& shadersExecutions)
630                                 : ThreadGroupThread             (context, pipelineCache, pipelineLayout, descriptorSetLayout, queues, shadersExecutions)
631                                 , m_pipelineInfo                (pipelineInfo)
632                                 , m_renderPass                  (renderPass)
633         {}
634
635         TestStatus      runThread               (void)
636         {
637                 ResultCollector         resultCollector;
638                 for (int executionNdx = 0; executionNdx < EXECUTION_PER_THREAD; ++executionNdx)
639                 {
640                         const int shaderNdx                                     = executionNdx % (int)m_pipelineInfo.size();
641                         const DeviceInterface&  vk                      = m_context.getDeviceInterface();
642                         const VkDevice                  device          = m_queues.getDevice();
643                         Move<VkPipeline>                pipeline        = createGraphicsPipeline(vk,device, m_pipelineCache, &m_pipelineInfo[shaderNdx]);
644
645                         TestStatus result = executeGraphicPipeline(m_context, *pipeline, m_pipelineLayout, m_descriptorSetLayout, m_queues, m_renderPass, m_shadersExecutions[shaderNdx]);
646                         resultCollector.addResult(result.getCode(), result.getDescription());
647                 }
648                 return TestStatus(resultCollector.getResult(), resultCollector.getMessage());
649         }
650
651 private:
652         vector<VkGraphicsPipelineCreateInfo>&   m_pipelineInfo;
653         const VkRenderPass&                                             m_renderPass;
654 };
655
656 class PipelineCacheComputeTestInstance  : public TestInstance
657 {
658         typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
659 public:
660                                 PipelineCacheComputeTestInstance        (Context& context, const vector<deUint32>& shadersExecutions)
661                                         : TestInstance                  (context)
662                                         , m_shadersExecutions   (shadersExecutions)
663
664         {
665         }
666
667         TestStatus      iterate                                                         (void)
668         {
669                 const DeviceInterface&                                  vk                                      = m_context.getDeviceInterface();
670                 MovePtr<MultiQueues>                                    queues                          = createQueues(m_context, VK_QUEUE_COMPUTE_BIT);
671                 const VkDevice                                                  device                          = queues->getDevice();
672                 ShaderModuleVector                                              shaderCompModules       = addShaderModules(device);
673                 Buffer                                                                  resultBuffer            (vk, device, *queues->m_allocator, makeBufferCreateInfo(BUFFER_SIZE, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
674                 const Move<VkDescriptorSetLayout>               descriptorSetLayout     (DescriptorSetLayoutBuilder()
675                                                                                                                                                 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_COMPUTE_BIT)
676                                                                                                                                                 .build(vk, device));
677                 const Move<VkPipelineLayout>                    pipelineLayout          (makePipelineLayout(vk, device, *descriptorSetLayout));
678                 vector<VkPipelineShaderStageCreateInfo> shaderStageInfos        = addShaderStageInfo(shaderCompModules);
679                 vector<VkComputePipelineCreateInfo>             pipelineInfo            = addPipelineInfo(*pipelineLayout, shaderStageInfos);
680                 const VkPipelineCacheCreateInfo                 pipelineCacheInfo       =
681                                                                                                                                         {
682                                                                                                                                                 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,   // VkStructureType             sType;
683                                                                                                                                                 DE_NULL,                                                                                // const void*                 pNext;
684                                                                                                                                                 0u,                                                                                             // VkPipelineCacheCreateFlags  flags;
685                                                                                                                                                 0u,                                                                                             // deUintptr                   initialDataSize;
686                                                                                                                                                 DE_NULL,                                                                                // const void*                 pInitialData;
687                                                                                                                                         };
688                 Move<VkPipelineCache>                                   pipelineCache           = createPipelineCache(vk, device, &pipelineCacheInfo);
689                 Move<VkPipeline>                                                pipeline                        = createComputePipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
690                 const deUint32                                                  numThreads                      = clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
691                 ThreadGroup                                                             threads;
692
693                 executeComputePipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions[0]);
694
695                 for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
696                         threads.add(MovePtr<ThreadGroupThread>(new CreateComputeThread(
697                                 m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, m_shadersExecutions)));
698
699                 {
700                         TestStatus thread_result = threads.run();
701                         if(thread_result.getCode())
702                         {
703                                 return thread_result;
704                         }
705                 }
706                 return TestStatus::pass("Passed");
707         }
708
709 private:
710         ShaderModuleVector                                                      addShaderModules                                        (const VkDevice& device)
711         {
712                 const DeviceInterface&  vk      = m_context.getDeviceInterface();
713                 ShaderModuleVector              shaderCompModules;
714                 shaderCompModules.resize(m_shadersExecutions.size());
715                 for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
716                 {
717                         ostringstream shaderName;
718                         shaderName<<"compute_"<<shaderNdx;
719                         shaderCompModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
720                 }
721                 return shaderCompModules;
722         }
723
724         vector<VkPipelineShaderStageCreateInfo>         addShaderStageInfo                                      (const ShaderModuleVector& shaderCompModules)
725         {
726                 VkPipelineShaderStageCreateInfo                 shaderStageInfo;
727                 vector<VkPipelineShaderStageCreateInfo> shaderStageInfos;
728                 shaderStageInfo.sType                           =       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
729                 shaderStageInfo.pNext                           =       DE_NULL;
730                 shaderStageInfo.flags                           =       (VkPipelineShaderStageCreateFlags)0;
731                 shaderStageInfo.stage                           =       VK_SHADER_STAGE_COMPUTE_BIT;
732                 shaderStageInfo.pName                           =       "main";
733                 shaderStageInfo.pSpecializationInfo     =       DE_NULL;
734
735                 for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
736                 {
737                         shaderStageInfo.module = *(*shaderCompModules[shaderNdx]);
738                         shaderStageInfos.push_back(shaderStageInfo);
739                 }
740                 return shaderStageInfos;
741         }
742
743         vector<VkComputePipelineCreateInfo>             addPipelineInfo                                         (VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos)
744         {
745                 vector<VkComputePipelineCreateInfo> pipelineInfos;
746                 VkComputePipelineCreateInfo     computePipelineInfo;
747                                                                         computePipelineInfo.sType                               = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
748                                                                         computePipelineInfo.pNext                               = DE_NULL;
749                                                                         computePipelineInfo.flags                               = (VkPipelineCreateFlags)0;
750                                                                         computePipelineInfo.layout                              = pipelineLayout;
751                                                                         computePipelineInfo.basePipelineHandle  = DE_NULL;
752                                                                         computePipelineInfo.basePipelineIndex   = 0;
753
754                 for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
755                 {
756                         computePipelineInfo.stage = shaderStageInfos[shaderNdx];
757                         pipelineInfos.push_back(computePipelineInfo);
758                 }
759                 return pipelineInfos;
760         }
761
762         const vector<deUint32>  m_shadersExecutions;
763 };
764
765 class PipelineCacheGraphicTestInstance  : public TestInstance
766 {
767         typedef vector<SharedPtr<Unique<VkShaderModule> > > ShaderModuleVector;
768 public:
769                                                                                         PipelineCacheGraphicTestInstance        (Context& context, const vector<deUint32>& shadersExecutions)
770                                                                 : TestInstance                  (context)
771                                                                 , m_shadersExecutions   (shadersExecutions)
772
773         {
774         }
775
776         TestStatus                                                              iterate                                                         (void)
777         {
778                 requireFeatures(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS);
779
780                 const DeviceInterface&                                  vk                                              = m_context.getDeviceInterface();
781                 MovePtr<MultiQueues>                                    queues                                  = createQueues (m_context, VK_QUEUE_GRAPHICS_BIT);
782                 const VkDevice                                                  device                                  = queues->getDevice();
783                 VkFormat                                                                colorFormat                             = VK_FORMAT_R8G8B8A8_UNORM;
784                 Move<VkRenderPass>                                              renderPass                              = createRenderPass(m_context, device, colorFormat);
785                 const Move<VkDescriptorSetLayout>               descriptorSetLayout             (DescriptorSetLayoutBuilder()
786                                                                                                                                                         .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT)
787                                                                                                                                                         .build(vk, device));
788                 ShaderModuleVector                                              shaderGraphicModules    = addShaderModules(device);
789                 const Move<VkPipelineLayout>                    pipelineLayout                  (makePipelineLayout(vk, device, *descriptorSetLayout));
790                 vector<VkPipelineShaderStageCreateInfo> shaderStageInfos                = addShaderStageInfo(shaderGraphicModules);
791                 vector<VkGraphicsPipelineCreateInfo>    pipelineInfo                    = addPipelineInfo(*pipelineLayout, shaderStageInfos, *renderPass);
792                 const VkPipelineCacheCreateInfo                 pipelineCacheInfo               =
793                                                                                                                                                 {
794                                                                                                                                                         VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,   // VkStructureType             sType;
795                                                                                                                                                         DE_NULL,                                                                                // const void*                 pNext;
796                                                                                                                                                         0u,                                                                                             // VkPipelineCacheCreateFlags  flags;
797                                                                                                                                                         0u,                                                                                             // deUintptr                   initialDataSize;
798                                                                                                                                                         DE_NULL,                                                                                // const void*                 pInitialData;
799                                                                                                                                                 };
800                 Move<VkPipelineCache>                                   pipelineCache                   = createPipelineCache(vk, device, &pipelineCacheInfo);
801                 Move<VkPipeline>                                                pipeline                                = createGraphicsPipeline(vk, device, *pipelineCache, &pipelineInfo[0]);
802                 const deUint32                                                  numThreads                              = clamp(deGetNumAvailableLogicalCores(), 4u, 32u);
803                 ThreadGroup                                                             threads;
804
805                 executeGraphicPipeline(m_context, *pipeline, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions[0]);
806
807                 for (deUint32 ndx = 0; ndx < numThreads; ++ndx)
808                         threads.add(MovePtr<ThreadGroupThread>(new CreateGraphicThread(
809                                 m_context, *pipelineCache, pipelineInfo, *pipelineLayout, *descriptorSetLayout, *queues, *renderPass, m_shadersExecutions)));
810
811                 {
812                         TestStatus thread_result = threads.run();
813                         if(thread_result.getCode())
814                         {
815                                 return thread_result;
816                         }
817                 }
818                 return TestStatus::pass("Passed");
819         }
820
821 private:
822         ShaderModuleVector                                              addShaderModules                                        (const VkDevice& device)
823         {
824                 const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
825                 ShaderModuleVector              shaderModules;
826                 shaderModules.resize(m_shadersExecutions.size() + 1);
827                 for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
828                 {
829                         ostringstream shaderName;
830                         shaderName<<"vert_"<<shaderNdx;
831                         shaderModules[shaderNdx] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get(shaderName.str()), (VkShaderModuleCreateFlags)0)));
832                 }
833                 shaderModules[m_shadersExecutions.size()] = SharedPtr<Unique<VkShaderModule> > (new Unique<VkShaderModule>(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), (VkShaderModuleCreateFlags)0)));
834                 return shaderModules;
835         }
836
837         vector<VkPipelineShaderStageCreateInfo> addShaderStageInfo                                      (const ShaderModuleVector& shaderCompModules)
838         {
839                 VkPipelineShaderStageCreateInfo                 shaderStageInfo;
840                 vector<VkPipelineShaderStageCreateInfo> shaderStageInfos;
841                 shaderStageInfo.sType                           =       VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
842                 shaderStageInfo.pNext                           =       DE_NULL;
843                 shaderStageInfo.flags                           =       (VkPipelineShaderStageCreateFlags)0;
844                 shaderStageInfo.pName                           =       "main";
845                 shaderStageInfo.pSpecializationInfo     =       DE_NULL;
846
847                 for (int shaderNdx = 0; shaderNdx <  static_cast<int>(m_shadersExecutions.size()); ++shaderNdx)
848                 {
849                         shaderStageInfo.stage   =       VK_SHADER_STAGE_VERTEX_BIT;
850                         shaderStageInfo.module  = *(*shaderCompModules[shaderNdx]);
851                         shaderStageInfos.push_back(shaderStageInfo);
852
853                         shaderStageInfo.stage   =       VK_SHADER_STAGE_FRAGMENT_BIT;
854                         shaderStageInfo.module  = *(*shaderCompModules[m_shadersExecutions.size()]);
855                         shaderStageInfos.push_back(shaderStageInfo);
856                 }
857                 return shaderStageInfos;
858         }
859
860         vector<VkGraphicsPipelineCreateInfo>    addPipelineInfo                                         (VkPipelineLayout pipelineLayout, const vector<VkPipelineShaderStageCreateInfo>& shaderStageInfos, const VkRenderPass& renderPass)
861         {
862                 VkExtent3D                                                              colorImageExtent        = makeExtent3D(1u, 1u, 1u);
863                 vector<VkGraphicsPipelineCreateInfo>    pipelineInfo;
864
865                 m_vertexInputStateParams.sType                                                          = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
866                 m_vertexInputStateParams.pNext                                                          = DE_NULL;
867                 m_vertexInputStateParams.flags                                                          = 0u;
868                 m_vertexInputStateParams.vertexBindingDescriptionCount          = 0u;
869                 m_vertexInputStateParams.pVertexBindingDescriptions                     = DE_NULL;
870                 m_vertexInputStateParams.vertexAttributeDescriptionCount        = 0u;
871                 m_vertexInputStateParams.pVertexAttributeDescriptions           = DE_NULL;
872
873                 m_inputAssemblyStateParams.sType                                        = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
874                 m_inputAssemblyStateParams.pNext                                        = DE_NULL;
875                 m_inputAssemblyStateParams.flags                                        = 0u;
876                 m_inputAssemblyStateParams.topology                                     = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
877                 m_inputAssemblyStateParams.primitiveRestartEnable       = VK_FALSE;
878
879                 m_viewport.x                    = 0.0f;
880                 m_viewport.y                    = 0.0f;
881                 m_viewport.width                = (float)colorImageExtent.width;
882                 m_viewport.height               = (float)colorImageExtent.height;
883                 m_viewport.minDepth             = 0.0f;
884                 m_viewport.maxDepth             = 1.0f;
885
886                 //TODO
887                 m_scissor.offset.x              = 0;
888                 m_scissor.offset.y              = 0;
889                 m_scissor.extent.width  = colorImageExtent.width;
890                 m_scissor.extent.height = colorImageExtent.height;
891
892                 m_viewportStateParams.sType                     = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
893                 m_viewportStateParams.pNext                     = DE_NULL;
894                 m_viewportStateParams.flags                     = 0u;
895                 m_viewportStateParams.viewportCount     = 1u;
896                 m_viewportStateParams.pViewports        = &m_viewport;
897                 m_viewportStateParams.scissorCount      = 1u;
898                 m_viewportStateParams.pScissors         = &m_scissor;
899
900                 m_rasterStateParams.sType                                       = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
901                 m_rasterStateParams.pNext                                       = DE_NULL;
902                 m_rasterStateParams.flags                                       = 0u;
903                 m_rasterStateParams.depthClampEnable            = VK_FALSE;
904                 m_rasterStateParams.rasterizerDiscardEnable     = VK_FALSE;
905                 m_rasterStateParams.polygonMode                         = VK_POLYGON_MODE_FILL;
906                 m_rasterStateParams.cullMode                            = VK_CULL_MODE_NONE;
907                 m_rasterStateParams.frontFace                           = VK_FRONT_FACE_COUNTER_CLOCKWISE;
908                 m_rasterStateParams.depthBiasEnable                     = VK_FALSE;
909                 m_rasterStateParams.depthBiasConstantFactor     = 0.0f;
910                 m_rasterStateParams.depthBiasClamp                      = 0.0f;
911                 m_rasterStateParams.depthBiasSlopeFactor        = 0.0f;
912                 m_rasterStateParams.lineWidth                           = 1.0f;
913
914                 m_colorBlendAttachmentState.blendEnable                 = VK_FALSE;
915                 m_colorBlendAttachmentState.srcColorBlendFactor = VK_BLEND_FACTOR_ONE;
916                 m_colorBlendAttachmentState.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
917                 m_colorBlendAttachmentState.colorBlendOp                = VK_BLEND_OP_ADD;
918                 m_colorBlendAttachmentState.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
919                 m_colorBlendAttachmentState.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
920                 m_colorBlendAttachmentState.alphaBlendOp                = VK_BLEND_OP_ADD;
921                 m_colorBlendAttachmentState.colorWriteMask              = VK_COLOR_COMPONENT_R_BIT |
922                                                                                                                   VK_COLOR_COMPONENT_G_BIT |
923                                                                                                                   VK_COLOR_COMPONENT_B_BIT |
924                                                                                                                   VK_COLOR_COMPONENT_A_BIT;
925
926                 m_colorBlendStateParams.sType                           = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
927                 m_colorBlendStateParams.pNext                           = DE_NULL;
928                 m_colorBlendStateParams.flags                           = 0u;
929                 m_colorBlendStateParams.logicOpEnable           = VK_FALSE;
930                 m_colorBlendStateParams.logicOp                         = VK_LOGIC_OP_COPY;
931                 m_colorBlendStateParams.attachmentCount         = 1u;
932                 m_colorBlendStateParams.pAttachments            = &m_colorBlendAttachmentState;
933                 m_colorBlendStateParams.blendConstants[0]       = 0.0f;
934                 m_colorBlendStateParams.blendConstants[1]       = 0.0f;
935                 m_colorBlendStateParams.blendConstants[2]       = 0.0f;
936                 m_colorBlendStateParams.blendConstants[3]       = 0.0f;
937
938                 m_multisampleStateParams.sType                                  = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
939                 m_multisampleStateParams.pNext                                  = DE_NULL;
940                 m_multisampleStateParams.flags                                  = 0u;
941                 m_multisampleStateParams.rasterizationSamples   = VK_SAMPLE_COUNT_1_BIT;
942                 m_multisampleStateParams.sampleShadingEnable    = VK_FALSE;
943                 m_multisampleStateParams.minSampleShading               = 0.0f;
944                 m_multisampleStateParams.pSampleMask                    = DE_NULL;
945                 m_multisampleStateParams.alphaToCoverageEnable  = VK_FALSE;
946                 m_multisampleStateParams.alphaToOneEnable               = VK_FALSE;
947
948                 m_depthStencilStateParams.sType                                 = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
949                 m_depthStencilStateParams.pNext                                 = DE_NULL;
950                 m_depthStencilStateParams.flags                                 = 0u;
951                 m_depthStencilStateParams.depthTestEnable               = VK_TRUE;
952                 m_depthStencilStateParams.depthWriteEnable              = VK_TRUE;
953                 m_depthStencilStateParams.depthCompareOp                = VK_COMPARE_OP_LESS_OR_EQUAL;
954                 m_depthStencilStateParams.depthBoundsTestEnable = VK_FALSE;
955                 m_depthStencilStateParams.stencilTestEnable             = VK_FALSE;
956                 m_depthStencilStateParams.front.failOp                  = VK_STENCIL_OP_KEEP;
957                 m_depthStencilStateParams.front.passOp                  = VK_STENCIL_OP_KEEP;
958                 m_depthStencilStateParams.front.depthFailOp             = VK_STENCIL_OP_KEEP;
959                 m_depthStencilStateParams.front.compareOp               = VK_COMPARE_OP_NEVER;
960                 m_depthStencilStateParams.front.compareMask             = 0u;
961                 m_depthStencilStateParams.front.writeMask               = 0u;
962                 m_depthStencilStateParams.front.reference               = 0u;
963                 m_depthStencilStateParams.back.failOp                   = VK_STENCIL_OP_KEEP;
964                 m_depthStencilStateParams.back.passOp                   = VK_STENCIL_OP_KEEP;
965                 m_depthStencilStateParams.back.depthFailOp              = VK_STENCIL_OP_KEEP;
966                 m_depthStencilStateParams.back.compareOp                = VK_COMPARE_OP_NEVER;
967                 m_depthStencilStateParams.back.compareMask              = 0u;
968                 m_depthStencilStateParams.back.writeMask                = 0u;
969                 m_depthStencilStateParams.back.reference                = 0u;
970                 m_depthStencilStateParams.minDepthBounds                = 0.0f;
971                 m_depthStencilStateParams.maxDepthBounds                = 1.0f;
972
973                 VkGraphicsPipelineCreateInfo    graphicsPipelineParams  =
974                                                                                                                                 {
975                                                                                                                                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
976                                                                                                                                         DE_NULL,                                                                                        // const void*                                                                          pNext;
977                                                                                                                                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
978                                                                                                                                         2u,                                                                                                     // deUint32                                                                                     stageCount;
979                                                                                                                                         DE_NULL,                                                                                        // const VkPipelineShaderStageCreateInfo*                       pStages;
980                                                                                                                                         &m_vertexInputStateParams,                                                      // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
981                                                                                                                                         &m_inputAssemblyStateParams,                                            // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
982                                                                                                                                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
983                                                                                                                                         &m_viewportStateParams,                                                         // const VkPipelineViewportStateCreateInfo*                     pViewportState;
984                                                                                                                                         &m_rasterStateParams,                                                           // const VkPipelineRasterizationStateCreateInfo*        pRasterState;
985                                                                                                                                         &m_multisampleStateParams,                                                      // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
986                                                                                                                                         &m_depthStencilStateParams,                                                     // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
987                                                                                                                                         &m_colorBlendStateParams,                                                       // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
988                                                                                                                                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
989                                                                                                                                         pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
990                                                                                                                                         renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
991                                                                                                                                         0u,                                                                                                     // deUint32                                                                                     subpass;
992                                                                                                                                         DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
993                                                                                                                                         0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
994                                                                                                                                 };
995                 for (int shaderNdx = 0; shaderNdx < static_cast<int>(m_shadersExecutions.size()) * 2; shaderNdx+=2)
996                 {
997                         graphicsPipelineParams.pStages = &shaderStageInfos[shaderNdx];
998                         pipelineInfo.push_back(graphicsPipelineParams);
999                 }
1000                 return pipelineInfo;
1001         }
1002
1003         const vector<deUint32>                                  m_shadersExecutions;
1004         VkPipelineVertexInputStateCreateInfo    m_vertexInputStateParams;
1005         VkPipelineInputAssemblyStateCreateInfo  m_inputAssemblyStateParams;
1006         VkViewport                                                              m_viewport;
1007         VkRect2D                                                                m_scissor;
1008         VkPipelineViewportStateCreateInfo               m_viewportStateParams;
1009         VkPipelineRasterizationStateCreateInfo  m_rasterStateParams;
1010         VkPipelineColorBlendAttachmentState             m_colorBlendAttachmentState;
1011         VkPipelineColorBlendStateCreateInfo             m_colorBlendStateParams;
1012         VkPipelineMultisampleStateCreateInfo    m_multisampleStateParams;
1013         VkPipelineDepthStencilStateCreateInfo   m_depthStencilStateParams;
1014 };
1015
1016 class PipelineCacheComputeTest : public TestCase
1017 {
1018 public:
1019                                                         PipelineCacheComputeTest        (TestContext&           testCtx,
1020                                                                                                                 const string&           name,
1021                                                                                                                 const string&           description)
1022                                                                 :TestCase       (testCtx, name, description)
1023         {
1024         }
1025
1026         void                                    initPrograms                            (SourceCollections&     programCollection) const
1027         {
1028                 ostringstream buffer;
1029                 buffer  << "layout(set = 0, binding = 0, std430) buffer Output\n"
1030                                 << "{\n"
1031                                 << "    int result[];\n"
1032                                 << "} sb_out;\n";
1033                 {
1034                         ostringstream src;
1035                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
1036                                 << "\n"
1037                                 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1038                                 << "\n"
1039                                 << buffer.str()
1040                                 << "void main (void)\n"
1041                                 << "{\n"
1042                                 << "    highp uint ndx = gl_GlobalInvocationID.x;\n"
1043                                 << "    sb_out.result[ndx] = int(ndx);\n"
1044                                 << "}\n";
1045                         programCollection.glslSources.add("compute_0") << glu::ComputeSource(src.str());
1046                 }
1047                 {
1048                         ostringstream src;
1049                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
1050                                 << "\n"
1051                                 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1052                                 << "\n"
1053                                 << buffer.str()
1054                                 << "void main (void)\n"
1055                                 << "{\n"
1056                                 << "    for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
1057                                 << "    {\n"
1058                                 << "            sb_out.result[ndx] = int(ndx);\n"
1059                                 << "    }\n"
1060                                 << "}\n";
1061                         programCollection.glslSources.add("compute_1") << glu::ComputeSource(src.str());
1062                 }
1063                 {
1064                         ostringstream src;
1065                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n"
1066                                 << "\n"
1067                                 << "layout(local_size_x = "<<BUFFER_ELEMENT_COUNT<<", local_size_y = 1, local_size_z = 1) in;\n"
1068                                 << "\n"
1069                                 << buffer.str()
1070                                 << "void main (void)\n"
1071                                 << "{\n"
1072                                 << "    highp uint ndx = gl_LocalInvocationID.x;\n"
1073                                 << "    sb_out.result[ndx] = int(ndx);\n"
1074                                 << "}\n";
1075                         programCollection.glslSources.add("compute_2") << glu::ComputeSource(src.str());
1076                 }
1077         }
1078
1079         TestInstance*                   createInstance                          (Context& context) const
1080         {
1081                 vector<deUint32>        shadersExecutions;
1082                 shadersExecutions.push_back(16u);       //compute_0
1083                 shadersExecutions.push_back(1u);        //compute_1
1084                 shadersExecutions.push_back(1u);        //compute_2
1085                 return new PipelineCacheComputeTestInstance(context, shadersExecutions);
1086         }
1087 };
1088
1089 class PipelineCacheGraphicTest : public TestCase
1090 {
1091 public:
1092                                                         PipelineCacheGraphicTest        (TestContext&           testCtx,
1093                                                                                                                 const string&           name,
1094                                                                                                                 const string&           description)
1095                                                                 :TestCase       (testCtx, name, description)
1096         {
1097
1098         }
1099
1100         void                                    initPrograms                            (SourceCollections&     programCollection) const
1101         {
1102                 ostringstream buffer;
1103                 buffer  << "layout(set = 0, binding = 0, std430) buffer Output\n"
1104                                 << "{\n"
1105                                 << "    int result[];\n"
1106                                 << "} sb_out;\n";
1107
1108                 // Vertex
1109                 {
1110                         std::ostringstream src;
1111                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1112                                 << "\n"
1113                                 << buffer.str()
1114                                 << "\n"
1115                                 << "void main (void)\n"
1116                                 << "{\n"
1117                                 << "   sb_out.result[gl_VertexIndex] = int(gl_VertexIndex);\n"
1118                                 << "}\n";
1119                         programCollection.glslSources.add("vert_0") << glu::VertexSource(src.str());
1120                 }
1121                 // Vertex
1122                 {
1123                         std::ostringstream src;
1124                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1125                                 << "\n"
1126                                 << buffer.str()
1127                                 << "\n"
1128                                 << "void main (void)\n"
1129                                 << "{\n"
1130                                 << "    for (highp uint ndx = 0u; ndx < "<<BUFFER_ELEMENT_COUNT<<"u; ndx++)\n"
1131                                 << "    {\n"
1132                                 << "            sb_out.result[ndx] = int(ndx);\n"
1133                                 << "    }\n"
1134                                 << "}\n";
1135                         programCollection.glslSources.add("vert_1") << glu::VertexSource(src.str());
1136                 }
1137                 // Vertex
1138                 {
1139                         std::ostringstream src;
1140                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1141                                 << "\n"
1142                                 << buffer.str()
1143                                 << "\n"
1144                                 << "void main (void)\n"
1145                                 << "{\n"
1146                                 << "    for (int ndx = "<<BUFFER_ELEMENT_COUNT-1<<"; ndx >= 0; ndx--)\n"
1147                                 << "    {\n"
1148                                 << "            sb_out.result[uint(ndx)] = ndx;\n"
1149                                 << "    }\n"
1150                                 << "}\n";
1151                         programCollection.glslSources.add("vert_2") << glu::VertexSource(src.str());
1152                 }
1153                 // Fragment
1154                 {
1155                         std::ostringstream src;
1156                         src     << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n"
1157                                 << "\n"
1158                                 << "layout(location = 0) out vec4 o_color;\n"
1159                                 << "\n"
1160                                 << "void main (void)\n"
1161                                 << "{\n"
1162                                 << "    o_color = vec4(1.0);\n"
1163                                 << "}\n";
1164                         programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
1165                 }
1166         }
1167
1168         TestInstance*                   createInstance                          (Context& context) const
1169         {
1170                 vector<deUint32>        shadersExecutions;
1171                 shadersExecutions.push_back(16u);       //vert_0
1172                 shadersExecutions.push_back(1u);        //vert_1
1173                 shadersExecutions.push_back(1u);        //vert_2
1174                 return new PipelineCacheGraphicTestInstance(context, shadersExecutions);
1175         }
1176 };
1177
1178
1179 } // anonymous
1180
1181 tcu::TestCaseGroup* createInternallySynchronizedObjects (tcu::TestContext& testCtx)
1182 {
1183         de::MovePtr<tcu::TestCaseGroup> tests(new tcu::TestCaseGroup(testCtx, "internally_synchronized_objects", "Internally synchronized objects"));
1184         tests->addChild(new PipelineCacheComputeTest(testCtx, "pipeline_cache_compute", "Internally synchronized object VkPipelineCache for compute pipeline is tested"));
1185         tests->addChild(new PipelineCacheGraphicTest(testCtx, "pipeline_cache_graphics", "Internally synchronized object VkPipelineCache for graphics pipeline is tested"));
1186         return tests.release();
1187 }
1188
1189 } // synchronization
1190 } // vkt