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 VkCommandPoolCreateInfo commandPoolInfo; 406 VkCommandBufferAllocateInfo commandBufferInfo; 407 VkCommandBuffer commandBuffer; 408 409 deMemset(&commandPoolInfo, 0xcd, sizeof(commandPoolInfo)); 410 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 411 commandPoolInfo.pNext = DE_NULL; 412 commandPoolInfo.flags = 0; 413 commandPoolInfo.queueFamilyIndex = queueFamilyNdx; 414 415 commandPool = createCommandPool(deviceInterface, device, &commandPoolInfo, DE_NULL); 416 417 deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo)); 418 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 419 commandBufferInfo.pNext = DE_NULL; 420 commandBufferInfo.commandPool = commandPool.get(); 421 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 422 commandBufferInfo.commandBufferCount = 1; 423 424 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer)); 425 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get())); 426 *commandPoolRef = commandPool; 427 } 428 429 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence) 430 { 431 VkFenceCreateInfo fenceState; 432 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0; 433 434 deMemset(&fenceState, 0xcd, sizeof(fenceState)); 435 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 436 fenceState.pNext = DE_NULL; 437 fenceState.flags = signalFlag; 438 439 for (deUint32 ndx = 0; ndx < numFences; ndx++) 440 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx])); 441 } 442 443 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence) 444 { 445 for (deUint32 ndx = 0; ndx < numFences; ndx++) 446 deviceInterface.destroyFence(device, fence[ndx], DE_NULL); 447 } 448 449 struct RenderInfo 450 { 451 deInt32 width; 452 deInt32 height; 453 deUint32 vertexBufferSize; 454 VkBuffer vertexBuffer; 455 VkImage image; 456 VkCommandBuffer commandBuffer; 457 VkRenderPass renderPass; 458 VkFramebuffer framebuffer; 459 VkPipeline pipeline; 460 deUint32 mipLevels; 461 const deUint32* queueFamilyNdxList; 462 deUint32 queueFamilyNdxCount; 463 bool waitEvent; 464 VkEvent event; 465 vector<VkImageMemoryBarrier>* barriers; 466 }; 467 468 void recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo) 469 { 470 const VkDeviceSize bindingOffset = 0; 471 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0); 472 VkRenderPassBeginInfo renderPassBeginState; 473 VkImageMemoryBarrier renderBarrier; 474 475 deMemset(&renderPassBeginState, 0xcd, sizeof(renderPassBeginState)); 476 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 477 renderPassBeginState.pNext = DE_NULL; 478 renderPassBeginState.renderPass = renderInfo.renderPass; 479 renderPassBeginState.framebuffer = renderInfo.framebuffer; 480 renderPassBeginState.renderArea.offset.x = 0; 481 renderPassBeginState.renderArea.offset.y = 0; 482 renderPassBeginState.renderArea.extent.width = renderInfo.width; 483 renderPassBeginState.renderArea.extent.height = renderInfo.height; 484 renderPassBeginState.clearValueCount = 1; 485 renderPassBeginState.pClearValues = &clearValue; 486 487 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE); 488 if (renderInfo.waitEvent) 489 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); 490 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline); 491 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset); 492 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0); 493 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer); 494 495 deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier)); 496 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; 497 renderBarrier.pNext = DE_NULL; 498 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 499 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT; 500 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 501 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL; 502 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0]; 503 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1]; 504 renderBarrier.image = renderInfo.image; 505 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 506 renderBarrier.subresourceRange.baseMipLevel = 0; 507 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels; 508 renderBarrier.subresourceRange.baseArrayLayer = 0; 509 renderBarrier.subresourceRange.layerCount = 1; 510 renderInfo.barriers->push_back(renderBarrier); 511 } 512 513 struct TransferInfo 514 { 515 VkCommandBuffer commandBuffer; 516 deUint32 width; 517 deUint32 height; 518 VkImage image; 519 VkBuffer buffer; 520 VkDeviceSize size; 521 deUint32 mipLevel; 522 VkOffset3D imageOffset; 523 vector<VkBufferMemoryBarrier>* barriers; 524 }; 525 526 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo) 527 { 528 VkBufferImageCopy copyState; 529 530 copyState.bufferOffset = 0; 531 copyState.bufferRowLength = transferInfo->width; 532 copyState.bufferImageHeight = transferInfo->height; 533 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 534 copyState.imageSubresource.mipLevel = transferInfo->mipLevel; 535 copyState.imageSubresource.baseArrayLayer = 0; 536 copyState.imageSubresource.layerCount = 1; 537 copyState.imageOffset = transferInfo->imageOffset; 538 copyState.imageExtent.width = (deInt32)(transferInfo->width); 539 copyState.imageExtent.height = (deInt32)(transferInfo->height); 540 copyState.imageExtent.depth = 1; 541 542 vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State); 543 544 { 545 VkBufferMemoryBarrier bufferBarrier; 546 deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier)); 547 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 548 bufferBarrier.pNext = DE_NULL; 549 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; 550 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT; 551 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 552 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; 553 bufferBarrier.buffer = transferInfo->buffer; 554 bufferBarrier.offset = 0; 555 bufferBarrier.size = transferInfo->size; 556 transferInfo->barriers->push_back(bufferBarrier); 557 } 558 } 559 560 struct TestContext 561 { 562 const DeviceInterface& vkd; 563 const VkDevice device; 564 const deUint32 queueFamilyIndex; 565 const BinaryCollection& binaryCollection; 566 Allocator& allocator; 567 568 const tcu::Vec4* vertices; 569 deUint32 numVertices; 570 tcu::IVec2 renderDimension; 571 VkFence fences[2]; 572 VkDeviceSize renderSize; 573 MovePtr<Allocation> renderReadBuffer; 574 MovePtr<Allocation> vertexBufferAllocation; 575 vk::Move<VkBuffer> vertexBuffer; 576 vk::Move<VkBuffer> renderBuffer; 577 bool waitEvent; 578 VkEvent event; 579 vk::Move<VkImage> image; 580 vk::Move<VkImageView> imageView; 581 vk::Move<VkFramebuffer> framebuffer; 582 vk::Move<VkCommandPool> commandPool; 583 vk::Move<VkCommandBuffer> cmdBuffer; 584 vk::Move<VkRenderPass> renderPass; 585 vk::Move<VkPipelineCache> pipelineCache; 586 vk::Move<VkPipeline> pipeline; 587 MovePtr<Allocation> imageAllocation; 588 589 TestContext (const DeviceInterface& vkd_, 590 const VkDevice device_, 591 deUint32 queueFamilyIndex_, 592 const BinaryCollection& binaryCollection_, 593 Allocator& allocator_) 594 : vkd (vkd_) 595 , device (device_) 596 , queueFamilyIndex (queueFamilyIndex_) 597 , binaryCollection (binaryCollection_) 598 , allocator (allocator_) 599 , numVertices (0) 600 , waitEvent (false) 601 { 602 createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences); 603 } 604 605 ~TestContext() 606 { 607 destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences); 608 } 609 }; 610 611 void generateWork (TestContext& testContext) 612 { 613 const DeviceInterface& deviceInterface = testContext.vkd; 614 const deUint32 queueFamilyNdx = testContext.queueFamilyIndex; 615 616 // \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted 617 // as pipeline has been constructed. 618 const vk::Unique<VkShaderModule> vertShaderModule (createShaderModule(deviceInterface, 619 testContext.device, 620 testContext.binaryCollection.get("glslvert"), 621 (VkShaderModuleCreateFlags)0)); 622 623 const vk::Unique<VkShaderModule> fragShaderModule (createShaderModule(deviceInterface, 624 testContext.device, 625 testContext.binaryCollection.get("glslfrag"), 626 (VkShaderModuleCreateFlags)0)); 627 const VkPipelineShaderStageCreateInfo shaderStageParams[] = 628 { 629 { 630 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 631 DE_NULL, 632 (VkPipelineShaderStageCreateFlags)0, 633 VK_SHADER_STAGE_VERTEX_BIT, 634 *vertShaderModule, 635 "main", 636 (const VkSpecializationInfo*)DE_NULL, 637 }, 638 { 639 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, 640 DE_NULL, 641 (VkPipelineShaderStageCreateFlags)0, 642 VK_SHADER_STAGE_FRAGMENT_BIT, 643 *fragShaderModule, 644 "main", 645 (const VkSpecializationInfo*)DE_NULL, 646 } 647 }; 648 649 vk::Move<VkPipelineLayout> layout; 650 vector<ShaderDescParams> shaderDescParams; 651 VertexDesc vertexDesc; 652 vector<VertexDesc> vertexDescList; 653 vector<VkVertexInputAttributeDescription> attrList; 654 vector<VkBufferMemoryBarrier> bufferMemoryBarrier; 655 deUint32 memoryBarrierNdx; 656 deUint32 bufferMemoryBarrierNdx; 657 deUint32 imageMemoryBarrierNdx; 658 vector<VkVertexInputBindingDescription> bindingList; 659 VkPipelineVertexInputStateCreateInfo vertexInputState; 660 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState; 661 VkPipelineDepthStencilStateCreateInfo depthStencilState; 662 VkPipelineColorBlendAttachmentState blendAttachment; 663 VkPipelineColorBlendStateCreateInfo blendState; 664 VkPipelineLayoutCreateInfo pipelineLayoutState; 665 VkGraphicsPipelineCreateInfo pipelineState; 666 VkPipelineCacheCreateInfo cacheState; 667 VkViewport viewport; 668 VkPipelineViewportStateCreateInfo viewportInfo; 669 VkRect2D scissor; 670 BufferParameters bufferParameters; 671 Buffer buffer; 672 RenderInfo renderInfo; 673 ImageParameters imageParameters; 674 Image image; 675 VkPipelineRasterizationStateCreateInfo rasterState; 676 VkPipelineMultisampleStateCreateInfo multisampleState; 677 VkFramebufferCreateInfo fbState; 678 VkCommandBufferBeginInfo commandBufRecordState; 679 VkCommandBufferInheritanceInfo inheritanceInfo; 680 RenderPassParameters renderPassParameters; 681 TransferInfo transferInfo; 682 vector<void*> barrierList; 683 VkExtent3D extent; 684 vector<VkMemoryBarrier> memoryBarriers; 685 vector<VkBufferMemoryBarrier> bufferBarriers; 686 vector<VkImageMemoryBarrier> imageBarriers; 687 688 memoryBarrierNdx = 0; 689 bufferMemoryBarrierNdx = 0; 690 imageMemoryBarrierNdx = 0; 691 buffer.memoryBarrier.resize(memoryBarrierNdx); 692 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx); 693 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx); 694 695 memoryBarriers.resize(0); 696 bufferBarriers.resize(0); 697 imageBarriers.resize(0); 698 699 bufferParameters.memory = testContext.vertices; 700 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4); 701 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; 702 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 703 bufferParameters.queueFamilyCount = 1; 704 bufferParameters.queueFamilyIndex = &queueFamilyNdx; 705 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; 706 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible); 707 testContext.vertexBufferAllocation = buffer.allocation; 708 testContext.vertexBuffer = buffer.buffer; 709 710 bufferParameters.memory = DE_NULL; 711 bufferParameters.size = testContext.renderSize; 712 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT; 713 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 714 bufferParameters.queueFamilyCount = 1; 715 bufferParameters.queueFamilyIndex = &queueFamilyNdx; 716 bufferParameters.inputBarrierFlags = 0; 717 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible); 718 testContext.renderReadBuffer = buffer.allocation; 719 testContext.renderBuffer = buffer.buffer; 720 721 extent.width = testContext.renderDimension.x(); 722 extent.height = testContext.renderDimension.y(); 723 extent.depth = 1; 724 725 imageParameters.imageType = VK_IMAGE_TYPE_2D; 726 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM; 727 imageParameters.extent3D = extent; 728 imageParameters.mipLevels = 1; 729 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT; 730 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL; 731 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 732 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 733 imageParameters.queueFamilyCount = 1; 734 imageParameters.queueFamilyNdxList = &queueFamilyNdx; 735 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 736 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 737 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 738 createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any); 739 testContext.imageAllocation = image.allocation; 740 testContext.image = image.image; 741 742 for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx) 743 imageBarriers.push_back(image.imageMemoryBarrier[ndx]); 744 745 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 746 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT; 747 createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass); 748 749 vertexDesc.location = 0; 750 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT; 751 vertexDesc.stride = sizeof(tcu::Vec4); 752 vertexDesc.offset = 0; 753 vertexDescList.push_back(vertexDesc); 754 755 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState); 756 757 deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState)); 758 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 759 inputAssemblyState.pNext = DE_NULL; 760 inputAssemblyState.flags = 0u; 761 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 762 inputAssemblyState.primitiveRestartEnable = false; 763 764 viewport.x = 0; 765 viewport.y = 0; 766 viewport.width = (float)testContext.renderDimension.x(); 767 viewport.height = (float)testContext.renderDimension.y(); 768 viewport.minDepth = 0; 769 viewport.maxDepth = 1; 770 771 scissor.offset.x = 0; 772 scissor.offset.y = 0; 773 scissor.extent.width = testContext.renderDimension.x(); 774 scissor.extent.height = testContext.renderDimension.y(); 775 776 deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo)); 777 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 778 viewportInfo.pNext = DE_NULL; 779 viewportInfo.flags = 0; 780 viewportInfo.viewportCount = 1; 781 viewportInfo.pViewports = &viewport; 782 viewportInfo.scissorCount = 1; 783 viewportInfo.pScissors = &scissor; 784 785 deMemset(&rasterState, 0xcd, sizeof(rasterState)); 786 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 787 rasterState.pNext = DE_NULL; 788 rasterState.flags = 0; 789 rasterState.depthClampEnable = VK_TRUE; 790 rasterState.rasterizerDiscardEnable = VK_FALSE; 791 rasterState.polygonMode = VK_POLYGON_MODE_FILL; 792 rasterState.cullMode = VK_CULL_MODE_NONE; 793 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; 794 rasterState.depthBiasEnable = VK_FALSE; 795 rasterState.lineWidth = 1; 796 797 deMemset(&multisampleState, 0xcd, sizeof(multisampleState)); 798 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 799 multisampleState.pNext = DE_NULL; 800 multisampleState.flags = 0; 801 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 802 multisampleState.sampleShadingEnable = VK_FALSE; 803 multisampleState.pSampleMask = DE_NULL; 804 multisampleState.alphaToCoverageEnable = VK_FALSE; 805 multisampleState.alphaToOneEnable = VK_FALSE; 806 807 deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState)); 808 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 809 depthStencilState.pNext = DE_NULL; 810 depthStencilState.flags = 0; 811 depthStencilState.depthTestEnable = VK_FALSE; 812 depthStencilState.depthWriteEnable = VK_FALSE; 813 depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS; 814 depthStencilState.depthBoundsTestEnable = VK_FALSE; 815 depthStencilState.stencilTestEnable = VK_FALSE; 816 depthStencilState.front.failOp = VK_STENCIL_OP_KEEP; 817 depthStencilState.front.passOp = VK_STENCIL_OP_KEEP; 818 depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP; 819 depthStencilState.front.compareOp = VK_COMPARE_OP_ALWAYS; 820 depthStencilState.front.compareMask = 0u; 821 depthStencilState.front.writeMask = 0u; 822 depthStencilState.front.reference = 0u; 823 depthStencilState.back = depthStencilState.front; 824 825 deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment)); 826 blendAttachment.blendEnable = VK_FALSE; 827 blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; 828 blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 829 blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; 830 blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 831 blendAttachment.colorBlendOp = VK_BLEND_OP_ADD; 832 blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; 833 blendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 834 835 deMemset(&blendState, 0xcd, sizeof(blendState)); 836 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 837 blendState.pNext = DE_NULL; 838 blendState.flags = 0; 839 blendState.logicOpEnable = VK_FALSE; 840 blendState.logicOp = VK_LOGIC_OP_COPY; 841 blendState.attachmentCount = 1; 842 blendState.pAttachments = &blendAttachment; 843 844 deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState)); 845 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 846 pipelineLayoutState.pNext = DE_NULL; 847 pipelineLayoutState.flags = 0; 848 pipelineLayoutState.setLayoutCount = 0; 849 pipelineLayoutState.pSetLayouts = DE_NULL; 850 pipelineLayoutState.pushConstantRangeCount = 0; 851 pipelineLayoutState.pPushConstantRanges = DE_NULL; 852 layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL); 853 854 deMemset(&pipelineState, 0xcd, sizeof(pipelineState)); 855 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 856 pipelineState.pNext = DE_NULL; 857 pipelineState.flags = 0; 858 pipelineState.stageCount = DE_LENGTH_OF_ARRAY(shaderStageParams); 859 pipelineState.pStages = &shaderStageParams[0]; 860 pipelineState.pVertexInputState = &vertexInputState; 861 pipelineState.pInputAssemblyState = &inputAssemblyState; 862 pipelineState.pTessellationState = DE_NULL; 863 pipelineState.pViewportState = &viewportInfo; 864 pipelineState.pRasterizationState = &rasterState; 865 pipelineState.pMultisampleState = &multisampleState; 866 pipelineState.pDepthStencilState = &depthStencilState; 867 pipelineState.pColorBlendState = &blendState; 868 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL; 869 pipelineState.layout = layout.get(); 870 pipelineState.renderPass = testContext.renderPass.get(); 871 pipelineState.subpass = 0; 872 pipelineState.basePipelineHandle = DE_NULL; 873 pipelineState.basePipelineIndex = 0; 874 875 deMemset(&cacheState, 0xcd, sizeof(cacheState)); 876 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO; 877 cacheState.pNext = DE_NULL; 878 cacheState.flags = 0; 879 cacheState.initialDataSize = 0; 880 cacheState.pInitialData = DE_NULL; 881 882 testContext.pipelineCache = createPipelineCache(deviceInterface, testContext.device, &cacheState); 883 testContext.pipeline = createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState); 884 885 deMemset(&fbState, 0xcd, sizeof(fbState)); 886 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 887 fbState.pNext = DE_NULL; 888 fbState.flags = 0; 889 fbState.renderPass = testContext.renderPass.get(); 890 fbState.attachmentCount = 1; 891 fbState.pAttachments = &image.imageView.get(); 892 fbState.width = (deUint32)testContext.renderDimension.x(); 893 fbState.height = (deUint32)testContext.renderDimension.y(); 894 fbState.layers = 1; 895 896 testContext.framebuffer = createFramebuffer(deviceInterface, testContext.device, &fbState); 897 testContext.imageView = image.imageView; 898 899 deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo)); 900 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; 901 inheritanceInfo.pNext = DE_NULL; 902 inheritanceInfo.renderPass = testContext.renderPass.get(); 903 inheritanceInfo.subpass = 0; 904 inheritanceInfo.framebuffer = *testContext.framebuffer; 905 inheritanceInfo.occlusionQueryEnable = VK_FALSE; 906 inheritanceInfo.queryFlags = 0u; 907 inheritanceInfo.pipelineStatistics = 0u; 908 909 deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState)); 910 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 911 commandBufRecordState.pNext = DE_NULL; 912 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; 913 commandBufRecordState.pInheritanceInfo = &inheritanceInfo; 914 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState)); 915 916 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(), 917 VK_PIPELINE_STAGE_HOST_BIT, 918 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 919 false, 920 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 921 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 922 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 923 924 memoryBarriers.resize(0); 925 bufferBarriers.resize(0); 926 imageBarriers.resize(0); 927 928 renderInfo.width = testContext.renderDimension.x(); 929 renderInfo.height = testContext.renderDimension.y(); 930 renderInfo.vertexBufferSize = testContext.numVertices; 931 renderInfo.vertexBuffer = testContext.vertexBuffer.get(); 932 renderInfo.image = testContext.image.get(); 933 renderInfo.commandBuffer = testContext.cmdBuffer.get(); 934 renderInfo.renderPass = testContext.renderPass.get(); 935 renderInfo.framebuffer = *testContext.framebuffer; 936 renderInfo.pipeline = *testContext.pipeline; 937 renderInfo.mipLevels = 1; 938 renderInfo.queueFamilyNdxList = &queueFamilyNdx; 939 renderInfo.queueFamilyNdxCount = 1; 940 renderInfo.waitEvent = testContext.waitEvent; 941 renderInfo.event = testContext.event; 942 renderInfo.barriers = &imageBarriers; 943 recordRenderPass(deviceInterface, renderInfo); 944 945 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer, 946 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 947 VK_PIPELINE_STAGE_TRANSFER_BIT, 948 false, 949 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 950 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 951 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 952 953 memoryBarriers.resize(0); 954 bufferBarriers.resize(0); 955 imageBarriers.resize(0); 956 957 transferInfo.commandBuffer = renderInfo.commandBuffer; 958 transferInfo.width = testContext.renderDimension.x(); 959 transferInfo.height = testContext.renderDimension.y(); 960 transferInfo.image = renderInfo.image; 961 transferInfo.buffer = testContext.renderBuffer.get(); 962 transferInfo.size = testContext.renderSize; 963 transferInfo.mipLevel = 0; 964 transferInfo.imageOffset.x = 0; 965 transferInfo.imageOffset.y = 0; 966 transferInfo.imageOffset.z = 0; 967 transferInfo.barriers = &bufferBarriers; 968 copyToCPU(deviceInterface, &transferInfo); 969 970 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer, 971 VK_PIPELINE_STAGE_TRANSFER_BIT, 972 VK_PIPELINE_STAGE_HOST_BIT, 973 false, 974 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]), 975 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]), 976 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0])); 977 978 memoryBarriers.resize(0); 979 bufferBarriers.resize(0); 980 imageBarriers.resize(0); 981 982 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer)); 983 } 984 985 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount) 986 { 987 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++) 988 { 989 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 990 submitInfo[ndx].pNext = DE_NULL; 991 submitInfo[ndx].waitSemaphoreCount = 0; 992 submitInfo[ndx].pWaitSemaphores = DE_NULL; 993 submitInfo[ndx].pWaitDstStageMask = DE_NULL; 994 submitInfo[ndx].commandBufferCount = 1; 995 submitInfo[ndx].signalSemaphoreCount = 0; 996 submitInfo[ndx].pSignalSemaphores = DE_NULL; 997 } 998 } 999 1000 tcu::TestStatus testFences (Context& context) 1001 { 1002 TestLog& log = context.getTestContext().getLog(); 1003 const DeviceInterface& deviceInterface = context.getDeviceInterface(); 1004 const VkQueue queue = context.getUniversalQueue(); 1005 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex(); 1006 VkDevice device = context.getDevice(); 1007 VkResult waitStatus; 1008 VkResult fenceStatus; 1009 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator()); 1010 VkSubmitInfo submitInfo; 1011 VkMappedMemoryRange range; 1012 void* resultImage; 1013 1014 const tcu::Vec4 vertices[] = 1015 { 1016 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1017 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1018 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1019 }; 1020 1021 testContext.vertices = vertices; 1022 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices); 1023 testContext.renderDimension = tcu::IVec2(256, 256); 1024 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y(); 1025 1026 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool); 1027 generateWork(testContext); 1028 1029 initSubmitInfo(&submitInfo, 1); 1030 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get(); 1031 1032 // Default status is unsignaled 1033 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]); 1034 if (fenceStatus != VK_NOT_READY) 1035 { 1036 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1037 return tcu::TestStatus::fail("Fence in incorrect state"); 1038 } 1039 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]); 1040 if (fenceStatus != VK_NOT_READY) 1041 { 1042 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1043 return tcu::TestStatus::fail("Fence in incorrect state"); 1044 } 1045 1046 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0])); 1047 1048 // Wait with timeout = 0 1049 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u); 1050 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT) 1051 { 1052 // Will most likely end with VK_TIMEOUT 1053 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage; 1054 return tcu::TestStatus::fail("Failed to wait for a single fence"); 1055 } 1056 1057 // Wait with a reasonable timeout 1058 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT); 1059 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT) 1060 { 1061 // \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient 1062 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage; 1063 return tcu::TestStatus::fail("Failed to wait for a single fence"); 1064 } 1065 1066 // Wait for work on fences[0] to actually complete 1067 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max()); 1068 if (waitStatus != VK_SUCCESS) 1069 { 1070 log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage; 1071 return tcu::TestStatus::fail("failed to wait for a fence"); 1072 } 1073 1074 // Wait until timeout on a fence that has not been submitted 1075 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1); 1076 if (waitStatus != VK_TIMEOUT) 1077 { 1078 log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage; 1079 return tcu::TestStatus::fail("failed to timeout on wait for single fence"); 1080 } 1081 1082 // Check that the fence is signaled after the wait 1083 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]); 1084 if (fenceStatus != VK_SUCCESS) 1085 { 1086 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage; 1087 return tcu::TestStatus::fail("Fence in incorrect state"); 1088 } 1089 1090 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1091 range.pNext = DE_NULL; 1092 range.memory = testContext.renderReadBuffer->getMemory(); 1093 range.offset = 0; 1094 range.size = testContext.renderSize; 1095 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range)); 1096 resultImage = testContext.renderReadBuffer->getHostPtr(); 1097 1098 log << TestLog::Image( "result", 1099 "result", 1100 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1101 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1102 testContext.renderDimension.x(), 1103 testContext.renderDimension.y(), 1104 1, 1105 resultImage)); 1106 1107 return TestStatus::pass("synchronization-fences passed"); 1108 } 1109 1110 vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks) 1111 { 1112 VkSemaphoreCreateInfo semaCreateInfo; 1113 VkSemaphore semaphore; 1114 1115 semaCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 1116 semaCreateInfo.pNext = DE_NULL; 1117 semaCreateInfo.flags = 0; 1118 VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore)); 1119 1120 return vk::check<VkSemaphore>(semaphore); 1121 } 1122 1123 tcu::TestStatus testSemaphores (Context& context) 1124 { 1125 TestLog& log = context.getTestContext().getLog(); 1126 const InstanceInterface& instanceInterface = context.getInstanceInterface(); 1127 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1128 deUint32 queueFamilyIdx; 1129 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx); 1130 const DeviceDriver deviceInterface (instanceInterface, *device); 1131 SimpleAllocator allocator (deviceInterface, 1132 *device, 1133 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice)); 1134 VkQueue queue[2]; 1135 VkResult testStatus; 1136 TestContext testContext1 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator); 1137 TestContext testContext2 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator); 1138 Unique<VkSemaphore> semaphore (createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL)); 1139 VkSubmitInfo submitInfo[2]; 1140 VkMappedMemoryRange range; 1141 void* resultImage; 1142 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 1143 1144 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]); 1145 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]); 1146 1147 const tcu::Vec4 vertices1[] = 1148 { 1149 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1150 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1151 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1152 }; 1153 1154 const tcu::Vec4 vertices2[] = 1155 { 1156 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f), 1157 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f), 1158 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f) 1159 }; 1160 1161 testContext1.vertices = vertices1; 1162 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1); 1163 testContext1.renderDimension = tcu::IVec2(256, 256); 1164 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y(); 1165 1166 testContext2.vertices = vertices2; 1167 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2); 1168 testContext2.renderDimension = tcu::IVec2(256, 256); 1169 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y(); 1170 1171 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool); 1172 generateWork(testContext1); 1173 1174 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool); 1175 generateWork(testContext2); 1176 1177 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo)); 1178 1179 // The difference between the two submit infos is that each will use a unique cmd buffer, 1180 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the 1181 // semaphore but not signal a semaphore 1182 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get(); 1183 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get(); 1184 1185 submitInfo[0].signalSemaphoreCount = 1; 1186 submitInfo[0].pSignalSemaphores = &semaphore.get(); 1187 submitInfo[1].waitSemaphoreCount = 1; 1188 submitInfo[1].pWaitSemaphores = &semaphore.get(); 1189 submitInfo[1].pWaitDstStageMask = &waitDstStageMask; 1190 1191 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0])); 1192 1193 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max()); 1194 if (testStatus != VK_SUCCESS) 1195 { 1196 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage; 1197 return tcu::TestStatus::fail("failed to wait for a set fence"); 1198 } 1199 1200 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1201 range.pNext = DE_NULL; 1202 range.memory = testContext1.renderReadBuffer->getMemory(); 1203 range.offset = 0; 1204 range.size = testContext1.renderSize; 1205 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range)); 1206 resultImage = testContext1.renderReadBuffer->getHostPtr(); 1207 1208 log << TestLog::Image( "result", 1209 "result", 1210 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1211 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1212 testContext1.renderDimension.x(), 1213 testContext1.renderDimension.y(), 1214 1, 1215 resultImage)); 1216 1217 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0])); 1218 1219 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max()); 1220 if (testStatus != VK_SUCCESS) 1221 { 1222 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage; 1223 return tcu::TestStatus::fail("failed to wait for a set fence"); 1224 } 1225 1226 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1227 range.pNext = DE_NULL; 1228 range.memory = testContext2.renderReadBuffer->getMemory(); 1229 range.offset = 0; 1230 range.size = testContext2.renderSize; 1231 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range)); 1232 resultImage = testContext2.renderReadBuffer->getHostPtr(); 1233 1234 log << TestLog::Image( "result", 1235 "result", 1236 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1237 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1238 testContext2.renderDimension.x(), 1239 testContext2.renderDimension.y(), 1240 1, 1241 resultImage)); 1242 1243 return tcu::TestStatus::pass("synchronization-semaphores passed"); 1244 } 1245 1246 vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks) 1247 { 1248 VkEventCreateInfo eventCreateInfo; 1249 VkEvent event; 1250 1251 eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; 1252 eventCreateInfo.pNext = DE_NULL; 1253 eventCreateInfo.flags = 0; 1254 VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event)); 1255 1256 return vk::check<VkEvent>(event); 1257 } 1258 1259 tcu::TestStatus testEvents (Context& context) 1260 { 1261 TestLog& log = context.getTestContext().getLog(); 1262 const DeviceInterface& deviceInterface = context.getDeviceInterface(); 1263 VkDevice device = context.getDevice(); 1264 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex(); 1265 Allocator& allocator = context.getDefaultAllocator(); 1266 VkQueue queue = context.getUniversalQueue(); 1267 VkResult testStatus; 1268 VkResult eventStatus; 1269 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), allocator); 1270 Unique<VkEvent> event (createEvent(deviceInterface, device, (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device, DE_NULL)); 1271 VkSubmitInfo submitInfo; 1272 VkMappedMemoryRange range; 1273 void* resultImage; 1274 1275 const tcu::Vec4 vertices1[] = 1276 { 1277 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f), 1278 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f), 1279 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f) 1280 }; 1281 1282 testContext.vertices = vertices1; 1283 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices1); 1284 testContext.renderDimension = tcu::IVec2(256, 256); 1285 testContext.waitEvent = true; 1286 testContext.event = event.get(); 1287 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y(); 1288 1289 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool); 1290 generateWork(testContext); 1291 1292 initSubmitInfo(&submitInfo, 1); 1293 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get(); 1294 1295 // 6.3 An event is initially in the unsignaled state 1296 eventStatus = deviceInterface.getEventStatus(device, event.get()); 1297 if (eventStatus != VK_EVENT_RESET) 1298 { 1299 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage; 1300 return tcu::TestStatus::fail("Event in incorrect status"); 1301 } 1302 1303 // The recorded command buffer should wait at the top of the graphics pipe for an event signaled by the host and so should not 1304 // make forward progress as long as the event is not signaled 1305 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0])); 1306 1307 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 1); 1308 if (testStatus != VK_TIMEOUT) 1309 { 1310 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set event from host." << TestLog::EndMessage; 1311 return tcu::TestStatus::fail("failed to wait for event set from host"); 1312 } 1313 1314 // Should allow the recorded command buffer to finally make progress 1315 VK_CHECK(deviceInterface.setEvent(device, event.get())); 1316 eventStatus = deviceInterface.getEventStatus(device, event.get()); 1317 if (eventStatus != VK_EVENT_SET) 1318 { 1319 log << TestLog::Message << "testEvents failed to transition event to signaled state via setEvent call from host" << TestLog::EndMessage; 1320 return tcu::TestStatus::fail("failed to signal event from host"); 1321 } 1322 1323 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, ~(0ull)); 1324 if (testStatus != VK_SUCCESS) 1325 { 1326 log << TestLog::Message << "testSynchronizationPrimitives failed to proceed after set event from host." << TestLog::EndMessage; 1327 return tcu::TestStatus::fail("failed to proceed after event set from host"); 1328 } 1329 1330 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE; 1331 range.pNext = DE_NULL; 1332 range.memory = testContext.renderReadBuffer->getMemory(); 1333 range.offset = 0; 1334 range.size = testContext.renderSize; 1335 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range)); 1336 resultImage = testContext.renderReadBuffer->getHostPtr(); 1337 1338 log << TestLog::Image( "result", 1339 "result", 1340 tcu::ConstPixelBufferAccess(tcu::TextureFormat( 1341 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), 1342 testContext.renderDimension.x(), 1343 testContext.renderDimension.y(), 1344 1, 1345 resultImage)); 1346 1347 return tcu::TestStatus::pass("synchronization-events passed"); 1348 } 1349 1350 } // anonymous 1351 1352 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx) 1353 { 1354 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests")); 1355 1356 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences); 1357 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores); 1358 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents); 1359 1360 return synchTests.release(); 1361 } 1362 1363 } // synchronization 1364 } // vkt 1365