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