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