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
addQueueFamilyIndex(const deUint32 & queueFamilyIndex,const deUint32 & count)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
getQueueFamilyIndex(const int index)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
countQueueFamilyIndex(void)106 inline size_t countQueueFamilyIndex (void)
107 {
108 return m_queues.size();
109 }
110
getQueues(const int index)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
getFreeQueue(deUint32 & returnQueueFamilyIndex,VkQueue & returnQueues,int & returnQueueIndex)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
releaseQueue(const deUint32 & queueFamilyIndex,const int & queueIndex)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
setDevice(Move<VkDevice> device)148 inline void setDevice (Move<VkDevice> device)
149 {
150 m_logicalDevice = device;
151 }
152
getDevice(void)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
createAllocator(const Context & context,const VkDevice & device)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
checkQueueFlags(const VkQueueFlags & availableFlag,const VkQueueFlags & neededFlag)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
createQueues(const Context & context,const VkQueueFlags & queueFlag)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
executeComputePipeline(const Context & context,const VkPipeline & pipeline,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const deUint32 & shadersExecutions)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
executeGraphicPipeline(const Context & context,const VkPipeline & pipeline,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const VkRenderPass & renderPass,const deUint32 shadersExecutions)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),
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:
ThreadGroupThread(const Context & context,VkPipelineCache pipelineCache,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const vector<deUint32> & shadersExecutions)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
~ThreadGroupThread(void)460 virtual ~ThreadGroupThread (void)
461 {
462 }
463
getResultCollector(void)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
run(void)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:
ThreadGroup(void)513 ThreadGroup (void)
514 {
515 }
~ThreadGroup(void)516 ~ThreadGroup (void)
517 {
518 }
519
add(MovePtr<ThreadGroupThread> thread)520 void add (MovePtr<ThreadGroupThread> thread)
521 {
522 m_threads.push_back(SharedPtr<ThreadGroupThread>(thread.release()));
523 }
524
run(void)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:
CreateComputeThread(const Context & context,VkPipelineCache pipelineCache,vector<VkComputePipelineCreateInfo> & pipelineInfo,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const vector<deUint32> & shadersExecutions)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
runThread(void)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:
CreateGraphicThread(const Context & context,VkPipelineCache pipelineCache,vector<VkGraphicsPipelineCreateInfo> & pipelineInfo,const VkPipelineLayout & pipelineLayout,const VkDescriptorSetLayout & descriptorSetLayout,MultiQueues & queues,const VkRenderPass & renderPass,const vector<deUint32> & shadersExecutions)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
runThread(void)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:
PipelineCacheComputeTestInstance(Context & context,const vector<deUint32> & shadersExecutions)613 PipelineCacheComputeTestInstance (Context& context, const vector<deUint32>& shadersExecutions)
614 : TestInstance (context)
615 , m_shadersExecutions (shadersExecutions)
616
617 {
618 }
619
iterate(void)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:
addShaderModules(const VkDevice & device)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
addShaderStageInfo(const ShaderModuleVector & shaderCompModules)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
addPipelineInfo(VkPipelineLayout pipelineLayout,const vector<VkPipelineShaderStageCreateInfo> & shaderStageInfos)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:
PipelineCacheGraphicTestInstance(Context & context,const vector<deUint32> & shadersExecutions)722 PipelineCacheGraphicTestInstance (Context& context, const vector<deUint32>& shadersExecutions)
723 : TestInstance (context)
724 , m_shadersExecutions (shadersExecutions)
725
726 {
727 }
728
iterate(void)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:
addShaderModules(const VkDevice & device)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
addShaderStageInfo(const ShaderModuleVector & shaderCompModules)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
addPipelineInfo(VkPipelineLayout pipelineLayout,const vector<VkPipelineShaderStageCreateInfo> & shaderStageInfos,const VkRenderPass & renderPass)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:
PipelineCacheComputeTest(TestContext & testCtx,const string & name,const string & description)972 PipelineCacheComputeTest (TestContext& testCtx,
973 const string& name,
974 const string& description)
975 :TestCase (testCtx, name, description)
976 {
977 }
978
initPrograms(SourceCollections & programCollection) const979 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
createInstance(Context & context) const1032 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:
PipelineCacheGraphicTest(TestContext & testCtx,const string & name,const string & description)1045 PipelineCacheGraphicTest (TestContext& testCtx,
1046 const string& name,
1047 const string& description)
1048 :TestCase (testCtx, name, description)
1049 {
1050
1051 }
1052
initPrograms(SourceCollections & programCollection) const1053 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
createInstance(Context & context) const1124 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
createInternallySynchronizedObjects(tcu::TestContext & testCtx)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
1147