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