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