1 /*------------------------------------------------------------------------- 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 Google 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 Platform Synchronization tests 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktSynchronizationSmokeTests.hpp" 25 26 #include "vktTestCaseUtil.hpp" 27 28 #include "vkPlatform.hpp" 29 #include "vkStrUtil.hpp" 30 #include "vkRef.hpp" 31 #include "vkRefUtil.hpp" 32 #include "vkDeviceUtil.hpp" 33 34 #include "tcuTestLog.hpp" 35 #include "tcuFormatUtil.hpp" 36 37 #include "deUniquePtr.hpp" 38 #include "deThread.hpp" 39 #include "vkMemUtil.hpp" 40 #include "vkQueryUtil.hpp" 41 #include "vkPrograms.hpp" 42 #include "vkTypeUtil.hpp" 43 44 #include <limits> 45 46 namespace vkt 47 { 48 namespace synchronization 49 { 50 51 using namespace vk; 52 using namespace tcu; 53 54 namespace 55 { 56 57 using std::vector; 58 using std::string; 59 using tcu::TestLog; 60 using de::UniquePtr; 61 using de::MovePtr; 62 63 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds 64 65 void buildShaders (SourceCollections& shaderCollection) 66 { 67 shaderCollection.glslSources.add("glslvert") << 68 glu::VertexSource( 69 "#version 310 es\n" 70 "precision mediump float;\n" 71 "layout (location = 0) in vec4 vertexPosition;\n" 72 "void main()\n" 73 "{\n" 74 " gl_Position = vertexPosition;\n" 75 "}\n"); 76 77 shaderCollection.glslSources.add("glslfrag") << 78 glu::FragmentSource( 79 "#version 310 es\n" 80 "precision mediump float;\n" 81 "layout (location = 0) out vec4 outputColor;\n" 82 "void main()\n" 83 "{\n" 84 " outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n" 85 "}\n"); 86 } 87 88 Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *outQueueFamilyIndex) 89 { 90 VkDeviceQueueCreateInfo queueInfo; 91 VkDeviceCreateInfo deviceInfo; 92 size_t queueNdx; 93 const deUint32 queueCount = 2u; 94 const float queuePriority[queueCount] = { 1.0f, 1.0f }; 95 96 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice); 97 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice); 98 99 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++) 100 { 101 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount)) 102 break; 103 } 104 105 if (queueNdx >= queueProps.size()) 106 { 107 // No queue family index found 108 std::ostringstream msg; 109 msg << "Cannot create device with " << queueCount << " graphics queues"; 110 111 throw tcu::NotSupportedError(msg.str()); 112 } 113 114 deMemset(&queueInfo, 0, sizeof(queueInfo)); 115 deMemset(&deviceInfo, 0, sizeof(deviceInfo)); 116 117 deMemset(&queueInfo, 0xcd, sizeof(queueInfo)); 118 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 119 queueInfo.pNext = DE_NULL; 120 queueInfo.flags = (VkDeviceQueueCreateFlags)0u; 121 queueInfo.queueFamilyIndex = (deUint32)queueNdx; 122 queueInfo.queueCount = queueCount; 123 queueInfo.pQueuePriorities = queuePriority; 124 125 deMemset(&deviceInfo, 0xcd, sizeof(deviceInfo)); 126 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; 127 deviceInfo.pNext = DE_NULL; 128 deviceInfo.flags = (VkDeviceCreateFlags)0u; 129 deviceInfo.queueCreateInfoCount = 1u; 130 deviceInfo.pQueueCreateInfos = &queueInfo; 131 deviceInfo.enabledExtensionCount = 0u; 132 deviceInfo.ppEnabledExtensionNames = DE_NULL; 133 deviceInfo.enabledLayerCount = 0u; 134 deviceInfo.ppEnabledLayerNames = DE_NULL; 135 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures; 136 137 *outQueueFamilyIndex = queueInfo.queueFamilyIndex; 138 139 return createDevice(vki, physicalDevice, &deviceInfo); 140 }; 141 142 struct BufferParameters 143 { 144 const void* memory; 145 VkDeviceSize size; 146 VkBufferUsageFlags usage; 147 VkSharingMode sharingMode; 148 deUint32 queueFamilyCount; 149 const deUint32* queueFamilyIndex; 150 VkAccessFlags inputBarrierFlags; 151 }; 152 153 struct Buffer 154 { 155 MovePtr<Allocation> allocation; 156 vector<VkMemoryBarrier> memoryBarrier; 157 vk::Move<VkBuffer> buffer; 158 }; 159 160 void createVulkanBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility) 161 { 162 VkBufferCreateInfo bufferCreateParams; 163 164 deMemset(&bufferCreateParams, 0xcd, sizeof(bufferCreateParams)); 165 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 166 bufferCreateParams.pNext = DE_NULL; 167 bufferCreateParams.flags = 0; 168 bufferCreateParams.size = bufferParameters.size; 169 bufferCreateParams.usage = bufferParameters.usage; 170 bufferCreateParams.sharingMode = bufferParameters.sharingMode; 171 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount; 172 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex; 173 174 buffer.buffer = createBuffer(vkd, device, &bufferCreateParams); 175 buffer.allocation = allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer.buffer), visibility); 176 177 VK_CHECK(vkd.bindBufferMemory(device, *buffer.buffer, buffer.allocation->getMemory(), buffer.allocation->getOffset())); 178 179 // If caller provides a host memory buffer for the allocation, then go 180 // ahead and copy the provided data into the allocation and update the 181 // barrier list with the associated access 182 if (bufferParameters.memory != DE_NULL) 183 { 184 VkMemoryBarrier barrier; 185 VkMappedMemoryRange range; 186 187 deMemset(&range, 0xcd, sizeof(range)); 188 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 189 range.pNext = DE_NULL; 190 range.memory = buffer.allocation->getMemory(); 191 range.offset = buffer.allocation->getOffset(); 192 range.size = bufferParameters.size; 193 194 deMemcpy(buffer.allocation->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size); 195 VK_CHECK(vkd.flushMappedMemoryRanges(device, 1, &range)); 196 197 deMemset(&barrier, 0xcd, sizeof(barrier)); 198 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER; 199 barrier.pNext = DE_NULL; 200 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT; 201 barrier.dstAccessMask = bufferParameters.inputBarrierFlags; 202 203 buffer.memoryBarrier.push_back(barrier); 204 } 205 } 206 207 struct ImageParameters 208 { 209 VkImageType imageType; 210 VkFormat format; 211 VkExtent3D extent3D; 212 deUint32 mipLevels; 213 VkSampleCountFlagBits samples; 214 VkImageTiling tiling; 215 VkBufferUsageFlags usage; 216 VkSharingMode sharingMode; 217 deUint32 queueFamilyCount; 218 const deUint32* queueFamilyNdxList; 219 VkImageLayout initialLayout; 220 VkImageLayout finalLayout; 221 VkAccessFlags barrierInputMask; 222 }; 223 224 struct Image 225 { 226 vk::Move<VkImage> image; 227 vk::Move<VkImageView> imageView; 228 MovePtr<Allocation> allocation; 229 vector<VkImageMemoryBarrier> imageMemoryBarrier; 230 }; 231 232 void createVulkanImage (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility) 233 { 234 VkComponentMapping componentMap; 235 VkImageSubresourceRange subresourceRange; 236 VkImageViewCreateInfo imageViewCreateInfo; 237 VkImageCreateInfo imageCreateParams; 238 VkImageMemoryBarrier imageBarrier; 239 240 deMemset(&imageCreateParams, 0xcd, sizeof(imageCreateParams)); 241 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 242 imageCreateParams.pNext = DE_NULL; 243 imageCreateParams.flags = 0; 244 imageCreateParams.imageType = imageParameters.imageType; 245 imageCreateParams.format = imageParameters.format; 246 imageCreateParams.extent = imageParameters.extent3D; 247 imageCreateParams.mipLevels = imageParameters.mipLevels; 248 imageCreateParams.arrayLayers = 1; 249 imageCreateParams.samples = imageParameters.samples; 250 imageCreateParams.tiling = imageParameters.tiling; 251 imageCreateParams.usage = imageParameters.usage; 252 imageCreateParams.sharingMode = imageParameters.sharingMode; 253 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount; 254 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList; 255 imageCreateParams.initialLayout = imageParameters.initialLayout; 256 257 image.image = createImage(vkd, device, &imageCreateParams); 258 image.allocation = allocator.allocate(getImageMemoryRequirements(vkd, device, *image.image), visibility); 259 260 VK_CHECK(vkd.bindImageMemory(device, *image.image, image.allocation->getMemory(), image.allocation->getOffset())); 261 262 componentMap.r = VK_COMPONENT_SWIZZLE_R; 263 componentMap.g = VK_COMPONENT_SWIZZLE_G; 264 componentMap.b = VK_COMPONENT_SWIZZLE_B; 265 componentMap.a = VK_COMPONENT_SWIZZLE_A; 266 267 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 268 subresourceRange.baseMipLevel = 0; 269 subresourceRange.levelCount = imageParameters.mipLevels; 270 subresourceRange.baseArrayLayer = 0; 271 subresourceRange.layerCount = 1; 272 273 deMemset(&imageViewCreateInfo, 0xcd, sizeof(imageViewCreateInfo)); 274 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; 275 imageViewCreateInfo.pNext = DE_NULL; 276 imageViewCreateInfo.flags = 0; 277 imageViewCreateInfo.image = image.image.get(); 278 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D; 279 imageViewCreateInfo.format = imageParameters.format; 280 imageViewCreateInfo.components = componentMap; 281 imageViewCreateInfo.subresourceRange = subresourceRange; 282 283 image.imageView = createImageView(vkd, device, &imageViewCreateInfo); 284 285 deMemset(&imageBarrier, 0xcd, sizeof(imageBarrier)); 286 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 287 imageBarrier.pNext = DE_NULL; 288 imageBarrier.srcAccessMask = 0; 289 imageBarrier.dstAccessMask = imageParameters.barrierInputMask; 290 imageBarrier.oldLayout = imageParameters.initialLayout; 291 imageBarrier.newLayout = imageParameters.finalLayout; 292 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0]; 293 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1]; 294 imageBarrier.image = image.image.get(); 295 imageBarrier.subresourceRange = subresourceRange; 296 297 image.imageMemoryBarrier.push_back(imageBarrier); 298 } 299 300 struct RenderPassParameters 301 { 302 VkFormat colorFormat; 303 VkSampleCountFlagBits colorSamples; 304 }; 305 306 void createColorOnlyRenderPass (const DeviceInterface& vkd, VkDevice device, const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass) 307 { 308 VkAttachmentDescription colorAttachmentDesc; 309 VkAttachmentReference colorAttachmentRef; 310 VkAttachmentReference stencilAttachmentRef; 311 VkSubpassDescription subpassDesc; 312 VkRenderPassCreateInfo renderPassParams; 313 VkRenderPass newRenderPass; 314 315 colorAttachmentDesc.flags = 0; 316 colorAttachmentDesc.format = renderPassParameters.colorFormat; 317 colorAttachmentDesc.samples = renderPassParameters.colorSamples; 318 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 319 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 320 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 321 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 322 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 323 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 324 325 colorAttachmentRef.attachment = 0; 326 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 327 328 stencilAttachmentRef.attachment = VK_ATTACHMENT_UNUSED; 329 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED; 330 331 subpassDesc.flags = 0; 332 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 333 subpassDesc.inputAttachmentCount = 0; 334 subpassDesc.pInputAttachments = DE_NULL; 335 subpassDesc.colorAttachmentCount = 1; 336 subpassDesc.pColorAttachments = &colorAttachmentRef; 337 subpassDesc.pResolveAttachments = DE_NULL; 338 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef; 339 subpassDesc.preserveAttachmentCount = 0; 340 subpassDesc.pPreserveAttachments = DE_NULL; 341 342 deMemset(&renderPassParams, 0xcd, sizeof(renderPassParams)); 343 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 344 renderPassParams.pNext = DE_NULL; 345 renderPassParams.flags = 0; 346 renderPassParams.attachmentCount = 1; 347 renderPassParams.pAttachments = &colorAttachmentDesc; 348 renderPassParams.subpassCount = 1; 349 renderPassParams.pSubpasses = &subpassDesc; 350 renderPassParams.dependencyCount = 0; 351 renderPassParams.pDependencies = DE_NULL; 352 353 renderPass = createRenderPass(vkd, device, &renderPassParams); 354 } 355 356 struct ShaderDescParams 357 { 358 VkShaderModule shaderModule; 359 VkShaderStageFlagBits stage; 360 }; 361 362 struct VertexDesc 363 { 364 deUint32 location; 365 VkFormat format; 366 deUint32 stride; 367 deUint32 offset; 368 }; 369 370 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState) 371 { 372 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++) 373 { 374 deUint32 bindingId = 0; 375 VkVertexInputBindingDescription bindingDesc; 376 VkVertexInputAttributeDescription attrDesc; 377 378 bindingDesc.binding = bindingId; 379 bindingDesc.stride = vertDescIter->stride; 380 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 381 bindingList.push_back(bindingDesc); 382 383 attrDesc.location = vertDescIter->location; 384 attrDesc.binding = bindingId; 385 attrDesc.format = vertDescIter->format; 386 attrDesc.offset = vertDescIter->offset; 387 attrList.push_back(attrDesc); 388 389 bindingId++; 390 } 391 392 deMemset(&vertexInputState, 0xcd, sizeof(vertexInputState)); 393 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 394 vertexInputState.pNext = DE_NULL; 395 vertexInputState.flags = 0u; 396 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size(); 397 vertexInputState.pVertexBindingDescriptions = &bindingList[0]; 398 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size(); 399 vertexInputState.pVertexAttributeDescriptions = &attrList[0]; 400 } 401 402 void createCommandBuffer (const DeviceInterface& deviceInterface, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef, vk::Move<VkCommandPool>* commandPoolRef) 403 { 404 vk::Move<VkCommandPool> commandPool; 405 VkCommandBufferAllocateInfo commandBufferInfo; 406 VkCommandBuffer commandBuffer; 407 408 commandPool = createCommandPool(deviceInterface, device, 0u, queueFamilyNdx); 409 410 deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo)); 411 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 412 commandBufferInfo.pNext = DE_NULL; 413 commandBufferInfo.commandPool = commandPool.get(); 414 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 415 commandBufferInfo.commandBufferCount = 1; 416 417 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer)); 418 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get())); 419 *commandPoolRef = commandPool; 420 } 421 422 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence) 423 { 424 VkFenceCreateInfo fenceState; 425 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0; 426 427 deMemset(&fenceState, 0xcd, sizeof(fenceState)); 428 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 429 fenceState.pNext = DE_NULL; 430 fenceState.flags = signalFlag; 431 432 for (deUint32 ndx = 0; ndx < numFences; ndx++) 433 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx])); 434 } 435 436 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence) 437 { 438 for (deUint32 ndx = 0; ndx < numFences; ndx++) 439 deviceInterface.destroyFence(device, fence[ndx], DE_NULL); 440 } 441 442 struct RenderInfo 443 { 444 deInt32 width; 445 deInt32 height; 446 deUint32 vertexBufferSize; 447 VkBuffer vertexBuffer; 448 VkImage image; 449 VkCommandBuffer commandBuffer; 450 VkRenderPass renderPass; 451 VkFramebuffer framebuffer; 452 VkPipeline pipeline; 453 deUint32 mipLevels; 454 const deUint32* queueFamilyNdxList; 455 deUint32 queueFamilyNdxCount; 456 bool waitEvent; 457 VkEvent event; 458 vector<VkImageMemoryBarrier>* barriers; 459 }; 460 461 void recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo) 462 { 463 const VkDeviceSize bindingOffset = 0; 464 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0); 465 VkRenderPassBeginInfo renderPassBeginState; 466 VkImageMemoryBarrier renderBarrier; 467 468 deMemset(&renderPassBeginState, 0xcd, sizeof(renderPassBeginState)); 469 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 470 renderPassBeginState.pNext = DE_NULL; 471 renderPassBeginState.renderPass = renderInfo.renderPass; 472 renderPassBeginState.framebuffer = renderInfo.framebuffer; 473 renderPassBeginState.renderArea.offset.x = 0; 474 renderPassBeginState.renderArea.offset.y = 0; 475 renderPassBeginState.renderArea.extent.width = renderInfo.width; 476 renderPassBeginState.renderArea.extent.height = renderInfo.height; 477 renderPassBeginState.clearValueCount = 1; 478 renderPassBeginState.pClearValues = &clearValue; 479 480 if (renderInfo.waitEvent) 481 deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL); 482 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE); 483 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline); 484 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset); 485 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0); 486 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer); 487 488 deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier)); 489 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 490 renderBarrier.pNext = DE_NULL; 491 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 492 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 493 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 494 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 495 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0]; 496 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1]; 497 renderBarrier.image = renderInfo.image; 498 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 499 renderBarrier.subresourceRange.baseMipLevel = 0; 500 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels; 501 renderBarrier.subresourceRange.baseArrayLayer = 0; 502 renderBarrier.subresourceRange.layerCount = 1; 503 renderInfo.barriers->push_back(renderBarrier); 504 } 505 506 struct TransferInfo 507 { 508 VkCommandBuffer commandBuffer; 509 deUint32 width; 510 deUint32 height; 511 VkImage image; 512 VkBuffer buffer; 513 VkDeviceSize size; 514 deUint32 mipLevel; 515 VkOffset3D imageOffset; 516 vector<VkBufferMemoryBarrier>* barriers; 517 }; 518 519 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo) 520 { 521 VkBufferImageCopy copyState; 522 523 copyState.bufferOffset = 0; 524 copyState.bufferRowLength = transferInfo->width; 525 copyState.bufferImageHeight = transferInfo->height; 526 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 527 copyState.imageSubresource.mipLevel = transferInfo->mipLevel; 528 copyState.imageSubresource.baseArrayLayer = 0; 529 copyState.imageSubresource.layerCount = 1; 530 copyState.imageOffset = transferInfo->imageOffset; 531 copyState.imageExtent.width = (deInt32)(transferInfo->width); 532 copyState.imageExtent.height = (deInt32)(transferInfo->height); 533 copyState.imageExtent.depth = 1; 534 535 vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State); 536 537 { 538 VkBufferMemoryBarrier bufferBarrier; 539 deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier)); 540 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 541 bufferBarrier.pNext = DE_NULL; 542 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 543 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; 544 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 545 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 546 bufferBarrier.buffer = transferInfo->buffer; 547 bufferBarrier.offset = 0; 548 bufferBarrier.size = transferInfo->size; 549 transferInfo->barriers->push_back(bufferBarrier); 550 } 551 } 552 553 struct TestContext 554 { 555 const DeviceInterface& vkd; 556 const VkDevice device; 557 const deUint32 queueFamilyIndex; 558 const BinaryCollection& binaryCollection; 559 Allocator& allocator; 560 561 const tcu::Vec4* vertices; 562 deUint32 numVertices; 563 tcu::IVec2 renderDimension; 564 VkFence fences[2]; 565 VkDeviceSize renderSize; 566 MovePtr<Allocation> renderReadBuffer; 567 MovePtr<Allocation> vertexBufferAllocation; 568 vk::Move<VkBuffer> vertexBuffer; 569 vk::Move<VkBuffer> renderBuffer; 570 bool waitEvent; 571 VkEvent event; 572 vk::Move<VkImage> image; 573 vk::Move<VkImageView> imageView; 574 vk::Move<VkFramebuffer> framebuffer; 575 vk::Move<VkCommandPool> commandPool; 576 vk::Move<VkCommandBuffer> cmdBuffer; 577 vk::Move<VkRenderPass> renderPass; 578 vk::Move<VkPipelineCache> pipelineCache; 579 vk::Move<VkPipeline> pipeline; 580 MovePtr<Allocation> imageAllocation; 581 582 TestContext (const DeviceInterface& vkd_, 583 const VkDevice device_, 584 deUint32 queueFamilyIndex_, 585 const BinaryCollection& binaryCollection_, 586 Allocator& allocator_) 587 : vkd (vkd_) 588 , device (device_) 589 , queueFamilyIndex (queueFamilyIndex_) 590 , binaryCollection (binaryCollection_) 591 , allocator (allocator_) 592 , numVertices (0) 593 , waitEvent (false) 594 { 595 createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences); 596 } 597 598 ~TestContext() 599 { 600 destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences); 601 } 602 }; 603 604 void generateWork (TestContext& testContext) 605 { 606 const DeviceInterface& deviceInterface = testContext.vkd; 607 const deUint32 queueFamilyNdx = testContext.queueFamilyIndex; 608 609 // \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted 610 // as pipeline has been constructed. 611 const vk::Unique<VkShaderModule> vertShaderModule (createShaderModule(deviceInterface, 612 testContext.device, 613 testContext.binaryCollection.get("glslvert"), 614 (VkShaderModuleCreateFlags)0)); 615 616 const vk::Unique<VkShaderModule> fragShaderModule (createShaderModule(deviceInterface, 617 testContext.device, 618 testContext.binaryCollection.get("glslfrag"), 619 (VkShaderModuleCreateFlags)0)); 620 const VkPipelineShaderStageCreateInfo shaderStageParams[] = 621 { 622 { 623 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 624 DE_NULL, 625 (VkPipelineShaderStageCreateFlags)0, 626 VK_SHADER_STAGE_VERTEX_BIT, 627 *vertShaderModule, 628 "main", 629 (const VkSpecializationInfo*)DE_NULL, 630 }, 631 { 632 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 633 DE_NULL, 634 (VkPipelineShaderStageCreateFlags)0, 635 VK_SHADER_STAGE_FRAGMENT_BIT, 636 *fragShaderModule, 637 "main", 638 (const VkSpecializationInfo*)DE_NULL, 639 } 640 }; 641 642 vk::Move<VkPipelineLayout> layout; 643 vector<ShaderDescParams> shaderDescParams; 644 VertexDesc vertexDesc; 645 vector<VertexDesc> vertexDescList; 646 vector<VkVertexInputAttributeDescription> attrList; 647 vector<VkBufferMemoryBarrier> bufferMemoryBarrier; 648 deUint32 memoryBarrierNdx; 649 deUint32 bufferMemoryBarrierNdx; 650 deUint32 imageMemoryBarrierNdx; 651 vector<VkVertexInputBindingDescription> bindingList; 652 VkPipelineVertexInputStateCreateInfo vertexInputState; 653 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; 654 VkPipelineDepthStencilStateCreateInfo depthStencilState; 655 VkPipelineColorBlendAttachmentState blendAttachment; 656 VkPipelineColorBlendStateCreateInfo blendState; 657 VkPipelineLayoutCreateInfo pipelineLayoutState; 658 VkGraphicsPipelineCreateInfo pipelineState; 659 VkPipelineCacheCreateInfo cacheState; 660 VkViewport viewport; 661 VkPipelineViewportStateCreateInfo viewportInfo; 662 VkRect2D scissor; 663 BufferParameters bufferParameters; 664 Buffer buffer; 665 RenderInfo renderInfo; 666 ImageParameters imageParameters; 667 Image image; 668 VkPipelineRasterizationStateCreateInfo rasterState; 669 VkPipelineMultisampleStateCreateInfo multisampleState; 670 VkFramebufferCreateInfo fbState; 671 VkCommandBufferBeginInfo commandBufRecordState; 672 VkCommandBufferInheritanceInfo inheritanceInfo; 673 RenderPassParameters renderPassParameters; 674 TransferInfo transferInfo; 675 vector<void*> barrierList; 676 VkExtent3D extent; 677 vector<VkMemoryBarrier> memoryBarriers; 678 vector<VkBufferMemoryBarrier> bufferBarriers; 679 vector<VkImageMemoryBarrier> imageBarriers; 680 681 memoryBarrierNdx = 0; 682 bufferMemoryBarrierNdx = 0; 683 imageMemoryBarrierNdx = 0; 684 buffer.memoryBarrier.resize(memoryBarrierNdx); 685 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx); 686 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx); 687 688 memoryBarriers.resize(0); 689 bufferBarriers.resize(0); 690 imageBarriers.resize(0); 691 692 bufferParameters.memory = testContext.vertices; 693 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4); 694 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 695 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 696 bufferParameters.queueFamilyCount = 1; 697 bufferParameters.queueFamilyIndex = &queueFamilyNdx; 698 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; 699 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible); 700 testContext.vertexBufferAllocation = buffer.allocation; 701 testContext.vertexBuffer = buffer.buffer; 702 703 bufferParameters.memory = DE_NULL; 704 bufferParameters.size = testContext.renderSize; 705 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 706 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 707 bufferParameters.queueFamilyCount = 1; 708 bufferParameters.queueFamilyIndex = &queueFamilyNdx; 709 bufferParameters.inputBarrierFlags = 0; 710 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible); 711 testContext.renderReadBuffer = buffer.allocation; 712 testContext.renderBuffer = buffer.buffer; 713 714 extent.width = testContext.renderDimension.x(); 715 extent.height = testContext.renderDimension.y(); 716 extent.depth = 1; 717 718 imageParameters.imageType = VK_IMAGE_TYPE_2D; 719 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM; 720 imageParameters.extent3D = extent; 721 imageParameters.mipLevels = 1; 722 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT; 723 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL; 724 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 725 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 726 imageParameters.queueFamilyCount = 1; 727 imageParameters.queueFamilyNdxList = &queueFamilyNdx; 728 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 729 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 730 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 731 createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any); 732 testContext.imageAllocation = image.allocation; 733 testContext.image = image.image; 734 735 for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx) 736 imageBarriers.push_back(image.imageMemoryBarrier[ndx]); 737 738 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 739 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT; 740 createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass); 741 742 vertexDesc.location = 0; 743 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; 744 vertexDesc.stride = sizeof(tcu::Vec4); 745 vertexDesc.offset = 0; 746 vertexDescList.push_back(vertexDesc); 747 748 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState); 749 750 deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState)); 751 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 752 inputAssemblyState.pNext = DE_NULL; 753 inputAssemblyState.flags = 0u; 754 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 755 inputAssemblyState.primitiveRestartEnable = false; 756 757 viewport.x = 0; 758 viewport.y = 0; 759 viewport.width = (float)testContext.renderDimension.x(); 760 viewport.height = (float)testContext.renderDimension.y(); 761 viewport.minDepth = 0; 762 viewport.maxDepth = 1; 763 764 scissor.offset.x = 0; 765 scissor.offset.y = 0; 766 scissor.extent.width = testContext.renderDimension.x(); 767 scissor.extent.height = testContext.renderDimension.y(); 768 769 deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo)); 770 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 771 viewportInfo.pNext = DE_NULL; 772 viewportInfo.flags = 0; 773 viewportInfo.viewportCount = 1; 774 viewportInfo.pViewports = &viewport; 775 viewportInfo.scissorCount = 1; 776 viewportInfo.pScissors = &scissor; 777 778 deMemset(&rasterState, 0xcd, sizeof(rasterState)); 779 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 780 rasterState.pNext = DE_NULL; 781 rasterState.flags = 0; 782 rasterState.depthClampEnable = VK_TRUE; 783 rasterState.rasterizerDiscardEnable = VK_FALSE; 784 rasterState.polygonMode = VK_POLYGON_MODE_FILL; 785 rasterState.cullMode = VK_CULL_MODE_NONE; 786 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 787 rasterState.depthBiasEnable = VK_FALSE; 788 rasterState.lineWidth = 1; 789 790 deMemset(&multisampleState, 0xcd, sizeof(multisampleState)); 791 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 792 multisampleState.pNext = DE_NULL; 793 multisampleState.flags = 0; 794 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 795 multisampleState.sampleShadingEnable = VK_FALSE; 796 multisampleState.pSampleMask = DE_NULL; 797 multisampleState.alphaToCoverageEnable = VK_FALSE; 798 multisampleState.alphaToOneEnable = VK_FALSE; 799 800 deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState)); 801 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 802 depthStencilState.pNext = DE_NULL; 803 depthStencilState.flags = 0; 804 depthStencilState.depthTestEnable = VK_FALSE; 805 depthStencilState.depthWriteEnable = VK_FALSE; 806 depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS; 807 depthStencilState.depthBoundsTestEnable = VK_FALSE; 808 depthStencilState.stencilTestEnable = VK_FALSE; 809 depthStencilState.front.failOp = VK_STENCIL_OP_KEEP; 810 depthStencilState.front.passOp = VK_STENCIL_OP_KEEP; 811 depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP; 812 depthStencilState.front.compareOp = VK_COMPARE_OP_ALWAYS; 813 depthStencilState.front.compareMask = 0u; 814 depthStencilState.front.writeMask = 0u; 815 depthStencilState.front.reference = 0u; 816 depthStencilState.back = depthStencilState.front; 817 818 deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment)); 819 blendAttachment.blendEnable = VK_FALSE; 820 blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; 821 blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 822 blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; 823 blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 824 blendAttachment.colorBlendOp = VK_BLEND_OP_ADD; 825 blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; 826 blendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 827 828 deMemset(&blendState, 0xcd, sizeof(blendState)); 829 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 830 blendState.pNext = DE_NULL; 831 blendState.flags = 0; 832 blendState.logicOpEnable = VK_FALSE; 833 blendState.logicOp = VK_LOGIC_OP_COPY; 834 blendState.attachmentCount = 1; 835 blendState.pAttachments = &blendAttachment; 836 837 deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState)); 838 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 839 pipelineLayoutState.pNext = DE_NULL; 840 pipelineLayoutState.flags = 0; 841 pipelineLayoutState.setLayoutCount = 0; 842 pipelineLayoutState.pSetLayouts = DE_NULL; 843 pipelineLayoutState.pushConstantRangeCount = 0; 844 pipelineLayoutState.pPushConstantRanges = DE_NULL; 845 layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL); 846 847 deMemset(&pipelineState, 0xcd, sizeof(pipelineState)); 848 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 849 pipelineState.pNext = DE_NULL; 850 pipelineState.flags = 0; 851 pipelineState.stageCount = DE_LENGTH_OF_ARRAY(shaderStageParams); 852 pipelineState.pStages = &shaderStageParams[0]; 853 pipelineState.pVertexInputState = &vertexInputState; 854 pipelineState.pInputAssemblyState = &inputAssemblyState; 855 pipelineState.pTessellationState = DE_NULL; 856 pipelineState.pViewportState = &viewportInfo; 857 pipelineState.pRasterizationState = &rasterState; 858 pipelineState.pMultisampleState = &multisampleState; 859 pipelineState.pDepthStencilState = &depthStencilState; 860 pipelineState.pColorBlendState = &blendState; 861 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL; 862 pipelineState.layout = layout.get(); 863 pipelineState.renderPass = testContext.renderPass.get(); 864 pipelineState.subpass = 0; 865 pipelineState.basePipelineHandle = DE_NULL; 866 pipelineState.basePipelineIndex = 0; 867 868 deMemset(&cacheState, 0xcd, sizeof(cacheState)); 869 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 870 cacheState.pNext = DE_NULL; 871 cacheState.flags = 0; 872 cacheState.initialDataSize = 0; 873 cacheState.pInitialData = DE_NULL; 874 875 testContext.pipelineCache = createPipelineCache(deviceInterface, testContext.device, &cacheState); 876 testContext.pipeline = createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState); 877 878 deMemset(&fbState, 0xcd, sizeof(fbState)); 879 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 880 fbState.pNext = DE_NULL; 881 fbState.flags = 0; 882 fbState.renderPass = testContext.renderPass.get(); 883 fbState.attachmentCount = 1; 884 fbState.pAttachments = &image.imageView.get(); 885 fbState.width = (deUint32)testContext.renderDimension.x(); 886 fbState.height = (deUint32)testContext.renderDimension.y(); 887 fbState.layers = 1; 888 889 testContext.framebuffer = createFramebuffer(deviceInterface, testContext.device, &fbState); 890 testContext.imageView = image.imageView; 891 892 deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo)); 893 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 894 inheritanceInfo.pNext = DE_NULL; 895 inheritanceInfo.renderPass = testContext.renderPass.get(); 896 inheritanceInfo.subpass = 0; 897 inheritanceInfo.framebuffer = *testContext.framebuffer; 898 inheritanceInfo.occlusionQueryEnable = VK_FALSE; 899 inheritanceInfo.queryFlags = 0u; 900 inheritanceInfo.pipelineStatistics = 0u; 901 902 deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState)); 903 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 904 commandBufRecordState.pNext = DE_NULL; 905 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 906 commandBufRecordState.pInheritanceInfo = &inheritanceInfo; 907 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState)); 908 909 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(), 910 VK_PIPELINE_STAGE_HOST_BIT, 911 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 912 false, 913 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 914 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 915 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 916 917 memoryBarriers.resize(0); 918 bufferBarriers.resize(0); 919 imageBarriers.resize(0); 920 921 renderInfo.width = testContext.renderDimension.x(); 922 renderInfo.height = testContext.renderDimension.y(); 923 renderInfo.vertexBufferSize = testContext.numVertices; 924 renderInfo.vertexBuffer = testContext.vertexBuffer.get(); 925 renderInfo.image = testContext.image.get(); 926 renderInfo.commandBuffer = testContext.cmdBuffer.get(); 927 renderInfo.renderPass = testContext.renderPass.get(); 928 renderInfo.framebuffer = *testContext.framebuffer; 929 renderInfo.pipeline = *testContext.pipeline; 930 renderInfo.mipLevels = 1; 931 renderInfo.queueFamilyNdxList = &queueFamilyNdx; 932 renderInfo.queueFamilyNdxCount = 1; 933 renderInfo.waitEvent = testContext.waitEvent; 934 renderInfo.event = testContext.event; 935 renderInfo.barriers = &imageBarriers; 936 recordRenderPass(deviceInterface, renderInfo); 937 938 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer, 939 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 940 VK_PIPELINE_STAGE_TRANSFER_BIT, 941 false, 942 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 943 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 944 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 945 946 memoryBarriers.resize(0); 947 bufferBarriers.resize(0); 948 imageBarriers.resize(0); 949 950 transferInfo.commandBuffer = renderInfo.commandBuffer; 951 transferInfo.width = testContext.renderDimension.x(); 952 transferInfo.height = testContext.renderDimension.y(); 953 transferInfo.image = renderInfo.image; 954 transferInfo.buffer = testContext.renderBuffer.get(); 955 transferInfo.size = testContext.renderSize; 956 transferInfo.mipLevel = 0; 957 transferInfo.imageOffset.x = 0; 958 transferInfo.imageOffset.y = 0; 959 transferInfo.imageOffset.z = 0; 960 transferInfo.barriers = &bufferBarriers; 961 copyToCPU(deviceInterface, &transferInfo); 962 963 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer, 964 VK_PIPELINE_STAGE_TRANSFER_BIT, 965 VK_PIPELINE_STAGE_HOST_BIT, 966 false, 967 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 968 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 969 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 970 971 memoryBarriers.resize(0); 972 bufferBarriers.resize(0); 973 imageBarriers.resize(0); 974 975 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer)); 976 } 977 978 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount) 979 { 980 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++) 981 { 982 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 983 submitInfo[ndx].pNext = DE_NULL; 984 submitInfo[ndx].waitSemaphoreCount = 0; 985 submitInfo[ndx].pWaitSemaphores = DE_NULL; 986 submitInfo[ndx].pWaitDstStageMask = DE_NULL; 987 submitInfo[ndx].commandBufferCount = 1; 988 submitInfo[ndx].signalSemaphoreCount = 0; 989 submitInfo[ndx].pSignalSemaphores = DE_NULL; 990 } 991 } 992 993 tcu::TestStatus testFences (Context& context) 994 { 995 TestLog& log = context.getTestContext().getLog(); 996 const DeviceInterface& deviceInterface = context.getDeviceInterface(); 997 const VkQueue queue = context.getUniversalQueue(); 998 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex(); 999 VkDevice device = context.getDevice(); 1000 VkResult waitStatus; 1001 VkResult fenceStatus; 1002 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator()); 1003 VkSubmitInfo submitInfo; 1004 VkMappedMemoryRange range; 1005 void* resultImage; 1006 1007 const tcu::Vec4 vertices[] = 1008 { 1009 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1010 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1011 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1012 }; 1013 1014 testContext.vertices = vertices; 1015 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices); 1016 testContext.renderDimension = tcu::IVec2(256, 256); 1017 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y(); 1018 1019 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool); 1020 generateWork(testContext); 1021 1022 initSubmitInfo(&submitInfo, 1); 1023 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get(); 1024 1025 // Default status is unsignaled 1026 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]); 1027 if (fenceStatus != VK_NOT_READY) 1028 { 1029 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1030 return tcu::TestStatus::fail("Fence in incorrect state"); 1031 } 1032 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]); 1033 if (fenceStatus != VK_NOT_READY) 1034 { 1035 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1036 return tcu::TestStatus::fail("Fence in incorrect state"); 1037 } 1038 1039 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0])); 1040 1041 // Wait with timeout = 0 1042 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u); 1043 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT) 1044 { 1045 // Will most likely end with VK_TIMEOUT 1046 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage; 1047 return tcu::TestStatus::fail("Failed to wait for a single fence"); 1048 } 1049 1050 // Wait with a reasonable timeout 1051 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT); 1052 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT) 1053 { 1054 // \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient 1055 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage; 1056 return tcu::TestStatus::fail("Failed to wait for a single fence"); 1057 } 1058 1059 // Wait for work on fences[0] to actually complete 1060 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max()); 1061 if (waitStatus != VK_SUCCESS) 1062 { 1063 log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage; 1064 return tcu::TestStatus::fail("failed to wait for a fence"); 1065 } 1066 1067 // Wait until timeout on a fence that has not been submitted 1068 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1); 1069 if (waitStatus != VK_TIMEOUT) 1070 { 1071 log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage; 1072 return tcu::TestStatus::fail("failed to timeout on wait for single fence"); 1073 } 1074 1075 // Check that the fence is signaled after the wait 1076 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]); 1077 if (fenceStatus != VK_SUCCESS) 1078 { 1079 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1080 return tcu::TestStatus::fail("Fence in incorrect state"); 1081 } 1082 1083 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1084 range.pNext = DE_NULL; 1085 range.memory = testContext.renderReadBuffer->getMemory(); 1086 range.offset = 0; 1087 range.size = testContext.renderSize; 1088 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range)); 1089 resultImage = testContext.renderReadBuffer->getHostPtr(); 1090 1091 log << TestLog::Image( "result", 1092 "result", 1093 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1094 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1095 testContext.renderDimension.x(), 1096 testContext.renderDimension.y(), 1097 1, 1098 resultImage)); 1099 1100 return TestStatus::pass("synchronization-fences passed"); 1101 } 1102 1103 tcu::TestStatus testSemaphores (Context& context) 1104 { 1105 TestLog& log = context.getTestContext().getLog(); 1106 const InstanceInterface& instanceInterface = context.getInstanceInterface(); 1107 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1108 deUint32 queueFamilyIdx; 1109 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx); 1110 const DeviceDriver deviceInterface (instanceInterface, *device); 1111 SimpleAllocator allocator (deviceInterface, 1112 *device, 1113 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice)); 1114 const VkQueue queue[2] = 1115 { 1116 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 0), 1117 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 1) 1118 }; 1119 VkResult testStatus; 1120 TestContext testContext1 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator); 1121 TestContext testContext2 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator); 1122 Unique<VkSemaphore> semaphore (createSemaphore(deviceInterface, *device)); 1123 VkSubmitInfo submitInfo[2]; 1124 VkMappedMemoryRange range; 1125 void* resultImage; 1126 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1127 1128 const tcu::Vec4 vertices1[] = 1129 { 1130 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1131 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1132 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1133 }; 1134 1135 const tcu::Vec4 vertices2[] = 1136 { 1137 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), 1138 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f), 1139 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f) 1140 }; 1141 1142 testContext1.vertices = vertices1; 1143 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1); 1144 testContext1.renderDimension = tcu::IVec2(256, 256); 1145 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y(); 1146 1147 testContext2.vertices = vertices2; 1148 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2); 1149 testContext2.renderDimension = tcu::IVec2(256, 256); 1150 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y(); 1151 1152 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool); 1153 generateWork(testContext1); 1154 1155 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool); 1156 generateWork(testContext2); 1157 1158 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo)); 1159 1160 // The difference between the two submit infos is that each will use a unique cmd buffer, 1161 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the 1162 // semaphore but not signal a semaphore 1163 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get(); 1164 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get(); 1165 1166 submitInfo[0].signalSemaphoreCount = 1; 1167 submitInfo[0].pSignalSemaphores = &semaphore.get(); 1168 submitInfo[1].waitSemaphoreCount = 1; 1169 submitInfo[1].pWaitSemaphores = &semaphore.get(); 1170 submitInfo[1].pWaitDstStageMask = &waitDstStageMask; 1171 1172 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0])); 1173 1174 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max()); 1175 if (testStatus != VK_SUCCESS) 1176 { 1177 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage; 1178 return tcu::TestStatus::fail("failed to wait for a set fence"); 1179 } 1180 1181 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1182 range.pNext = DE_NULL; 1183 range.memory = testContext1.renderReadBuffer->getMemory(); 1184 range.offset = 0; 1185 range.size = testContext1.renderSize; 1186 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range)); 1187 resultImage = testContext1.renderReadBuffer->getHostPtr(); 1188 1189 log << TestLog::Image( "result", 1190 "result", 1191 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1192 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1193 testContext1.renderDimension.x(), 1194 testContext1.renderDimension.y(), 1195 1, 1196 resultImage)); 1197 1198 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0])); 1199 1200 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max()); 1201 if (testStatus != VK_SUCCESS) 1202 { 1203 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage; 1204 return tcu::TestStatus::fail("failed to wait for a set fence"); 1205 } 1206 1207 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1208 range.pNext = DE_NULL; 1209 range.memory = testContext2.renderReadBuffer->getMemory(); 1210 range.offset = 0; 1211 range.size = testContext2.renderSize; 1212 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range)); 1213 resultImage = testContext2.renderReadBuffer->getHostPtr(); 1214 1215 log << TestLog::Image( "result", 1216 "result", 1217 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1218 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1219 testContext2.renderDimension.x(), 1220 testContext2.renderDimension.y(), 1221 1, 1222 resultImage)); 1223 1224 return tcu::TestStatus::pass("synchronization-semaphores passed"); 1225 } 1226 1227 tcu::TestStatus testEvents (Context& context) 1228 { 1229 TestLog& log = context.getTestContext().getLog(); 1230 const DeviceInterface& deviceInterface = context.getDeviceInterface(); 1231 VkDevice device = context.getDevice(); 1232 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex(); 1233 Allocator& allocator = context.getDefaultAllocator(); 1234 VkQueue queue = context.getUniversalQueue(); 1235 VkResult testStatus; 1236 VkResult eventStatus; 1237 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), allocator); 1238 Unique<VkEvent> event (createEvent(deviceInterface, device)); 1239 VkSubmitInfo submitInfo; 1240 VkMappedMemoryRange range; 1241 void* resultImage; 1242 1243 const tcu::Vec4 vertices1[] = 1244 { 1245 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1246 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1247 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1248 }; 1249 1250 testContext.vertices = vertices1; 1251 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices1); 1252 testContext.renderDimension = tcu::IVec2(256, 256); 1253 testContext.waitEvent = true; 1254 testContext.event = event.get(); 1255 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y(); 1256 1257 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool); 1258 generateWork(testContext); 1259 1260 initSubmitInfo(&submitInfo, 1); 1261 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get(); 1262 1263 // 6.3 An event is initially in the unsignaled state 1264 eventStatus = deviceInterface.getEventStatus(device, event.get()); 1265 if (eventStatus != VK_EVENT_RESET) 1266 { 1267 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage; 1268 return tcu::TestStatus::fail("Event in incorrect status"); 1269 } 1270 1271 // The recorded command buffer should wait at the top of the graphics pipe for an event signaled by the host and so should not 1272 // make forward progress as long as the event is not signaled 1273 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0])); 1274 1275 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 10000000); 1276 if (testStatus != VK_TIMEOUT) 1277 { 1278 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set event from host." << TestLog::EndMessage; 1279 return tcu::TestStatus::fail("failed to wait for event set from host"); 1280 } 1281 1282 // Should allow the recorded command buffer to finally make progress 1283 VK_CHECK(deviceInterface.setEvent(device, event.get())); 1284 eventStatus = deviceInterface.getEventStatus(device, event.get()); 1285 if (eventStatus != VK_EVENT_SET) 1286 { 1287 log << TestLog::Message << "testEvents failed to transition event to signaled state via setEvent call from host" << TestLog::EndMessage; 1288 return tcu::TestStatus::fail("failed to signal event from host"); 1289 } 1290 1291 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, ~(0ull)); 1292 if (testStatus != VK_SUCCESS) 1293 { 1294 log << TestLog::Message << "testSynchronizationPrimitives failed to proceed after set event from host." << TestLog::EndMessage; 1295 return tcu::TestStatus::fail("failed to proceed after event set from host"); 1296 } 1297 1298 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1299 range.pNext = DE_NULL; 1300 range.memory = testContext.renderReadBuffer->getMemory(); 1301 range.offset = 0; 1302 range.size = testContext.renderSize; 1303 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range)); 1304 resultImage = testContext.renderReadBuffer->getHostPtr(); 1305 1306 log << TestLog::Image( "result", 1307 "result", 1308 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1309 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1310 testContext.renderDimension.x(), 1311 testContext.renderDimension.y(), 1312 1, 1313 resultImage)); 1314 1315 return tcu::TestStatus::pass("synchronization-events passed"); 1316 } 1317 1318 } // anonymous 1319 1320 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx) 1321 { 1322 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests")); 1323 1324 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences); 1325 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores); 1326 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents); 1327 1328 return synchTests.release(); 1329 } 1330 1331 } // synchronization 1332 } // vkt 1333