1 /*------------------------------------------------------------------------- 2 * Vulkan CTS Framework 3 * -------------------- 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * Copyright (c) 2016 Google Inc. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Utility for generating simple work 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktDrawUtil.hpp" 26 #include "rrMultisamplePixelBufferAccess.hpp" 27 #include "vkBufferWithMemory.hpp" 28 #include "vkImageWithMemory.hpp" 29 #include "vkTypeUtil.hpp" 30 #include "rrRenderer.hpp" 31 #include "rrRenderState.hpp" 32 #include "rrPrimitiveTypes.hpp" 33 #include "tcuTextureUtil.hpp" 34 #include "tcuTestLog.hpp" 35 #include "deArrayUtil.hpp" 36 #include "vkBuilderUtil.hpp" 37 38 namespace vkt 39 { 40 namespace drawutil 41 { 42 43 using namespace de; 44 using namespace tcu; 45 using namespace vk; 46 47 static VkCompareOp mapCompareOp (rr::TestFunc compareFunc) 48 { 49 switch (compareFunc) 50 { 51 case rr::TESTFUNC_NEVER: return VK_COMPARE_OP_NEVER; 52 case rr::TESTFUNC_LESS: return VK_COMPARE_OP_LESS; 53 case rr::TESTFUNC_EQUAL: return VK_COMPARE_OP_EQUAL; 54 case rr::TESTFUNC_LEQUAL: return VK_COMPARE_OP_LESS_OR_EQUAL; 55 case rr::TESTFUNC_GREATER: return VK_COMPARE_OP_GREATER; 56 case rr::TESTFUNC_NOTEQUAL: return VK_COMPARE_OP_NOT_EQUAL; 57 case rr::TESTFUNC_GEQUAL: return VK_COMPARE_OP_GREATER_OR_EQUAL; 58 case rr::TESTFUNC_ALWAYS: return VK_COMPARE_OP_ALWAYS; 59 default: 60 DE_ASSERT(false); 61 } 62 return VK_COMPARE_OP_LAST; 63 } 64 65 rr::PrimitiveType mapVkPrimitiveToRRPrimitive(const vk::VkPrimitiveTopology& primitiveTopology) 66 { 67 static const rr::PrimitiveType primitiveTypeTable[] = 68 { 69 rr::PRIMITIVETYPE_POINTS, 70 rr::PRIMITIVETYPE_LINES, 71 rr::PRIMITIVETYPE_LINE_STRIP, 72 rr::PRIMITIVETYPE_TRIANGLES, 73 rr::PRIMITIVETYPE_TRIANGLE_STRIP, 74 rr::PRIMITIVETYPE_TRIANGLE_FAN, 75 rr::PRIMITIVETYPE_LINES_ADJACENCY, 76 rr::PRIMITIVETYPE_LINE_STRIP_ADJACENCY, 77 rr::PRIMITIVETYPE_TRIANGLES_ADJACENCY, 78 rr::PRIMITIVETYPE_TRIANGLE_STRIP_ADJACENCY 79 }; 80 81 return de::getSizedArrayElement<vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST>(primitiveTypeTable, primitiveTopology); 82 } 83 84 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 85 const VkBufferUsageFlags usage) 86 { 87 const VkBufferCreateInfo bufferCreateInfo = 88 { 89 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 90 DE_NULL, // const void* pNext; 91 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 92 bufferSize, // VkDeviceSize size; 93 usage, // VkBufferUsageFlags usage; 94 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 95 0u, // deUint32 queueFamilyIndexCount; 96 DE_NULL, // const deUint32* pQueueFamilyIndices; 97 }; 98 return bufferCreateInfo; 99 } 100 101 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 102 const VkAccessFlags dstAccessMask, 103 const VkBuffer buffer, 104 const VkDeviceSize offset, 105 const VkDeviceSize bufferSizeBytes) 106 { 107 const VkBufferMemoryBarrier barrier = 108 { 109 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 110 DE_NULL, // const void* pNext; 111 srcAccessMask, // VkAccessFlags srcAccessMask; 112 dstAccessMask, // VkAccessFlags dstAccessMask; 113 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 114 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 115 buffer, // VkBuffer buffer; 116 offset, // VkDeviceSize offset; 117 bufferSizeBytes, // VkDeviceSize size; 118 }; 119 return barrier; 120 } 121 122 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 123 const VkAccessFlags dstAccessMask, 124 const VkImageLayout oldLayout, 125 const VkImageLayout newLayout, 126 const VkImage image, 127 const VkImageSubresourceRange subresourceRange) 128 { 129 const VkImageMemoryBarrier barrier = 130 { 131 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 132 DE_NULL, // const void* pNext; 133 srcAccessMask, // VkAccessFlags outputMask; 134 dstAccessMask, // VkAccessFlags inputMask; 135 oldLayout, // VkImageLayout oldLayout; 136 newLayout, // VkImageLayout newLayout; 137 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 138 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 139 image, // VkImage image; 140 subresourceRange, // VkImageSubresourceRange subresourceRange; 141 }; 142 return barrier; 143 } 144 145 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex) 146 { 147 const VkCommandPoolCreateInfo info = 148 { 149 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 150 DE_NULL, // const void* pNext; 151 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; 152 queueFamilyIndex, // deUint32 queueFamilyIndex; 153 }; 154 return createCommandPool(vk, device, &info); 155 } 156 157 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 158 { 159 const VkCommandBufferAllocateInfo info = 160 { 161 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 162 DE_NULL, // const void* pNext; 163 commandPool, // VkCommandPool commandPool; 164 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 165 1u, // deUint32 commandBufferCount; 166 }; 167 return allocateCommandBuffer(vk, device, &info); 168 } 169 170 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 171 const VkDevice device, 172 const VkDescriptorPool descriptorPool, 173 const VkDescriptorSetLayout setLayout) 174 { 175 const VkDescriptorSetAllocateInfo info = 176 { 177 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 178 DE_NULL, // const void* pNext; 179 descriptorPool, // VkDescriptorPool descriptorPool; 180 1u, // deUint32 descriptorSetCount; 181 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 182 }; 183 return allocateDescriptorSet(vk, device, &info); 184 } 185 186 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 187 const VkDevice device, 188 const VkDescriptorSetLayout descriptorSetLayout) 189 { 190 const VkPipelineLayoutCreateInfo info = 191 { 192 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 193 DE_NULL, // const void* pNext; 194 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 195 1u, // deUint32 setLayoutCount; 196 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 197 0u, // deUint32 pushConstantRangeCount; 198 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 199 }; 200 return createPipelineLayout(vk, device, &info); 201 } 202 203 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk, 204 const VkDevice device) 205 { 206 const VkPipelineLayoutCreateInfo info = 207 { 208 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 209 DE_NULL, // const void* pNext; 210 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 211 0u, // deUint32 setLayoutCount; 212 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 213 0u, // deUint32 pushConstantRangeCount; 214 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 215 }; 216 return createPipelineLayout(vk, device, &info); 217 } 218 219 Move<VkImageView> makeImageView (const DeviceInterface& vk, 220 const VkDevice device, 221 const VkImage image, 222 const VkImageViewType viewType, 223 const VkFormat format, 224 const VkImageSubresourceRange subresourceRange) 225 { 226 const VkImageViewCreateInfo imageViewParams = 227 { 228 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 229 DE_NULL, // const void* pNext; 230 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 231 image, // VkImage image; 232 viewType, // VkImageViewType viewType; 233 format, // VkFormat format; 234 makeComponentMappingRGBA(), // VkComponentMapping components; 235 subresourceRange, // VkImageSubresourceRange subresourceRange; 236 }; 237 return createImageView(vk, device, &imageViewParams); 238 } 239 240 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers, 241 const VkExtent3D extent) 242 { 243 const VkBufferImageCopy copyParams = 244 { 245 0ull, // VkDeviceSize bufferOffset; 246 0u, // deUint32 bufferRowLength; 247 0u, // deUint32 bufferImageHeight; 248 subresourceLayers, // VkImageSubresourceLayers imageSubresource; 249 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 250 extent, // VkExtent3D imageExtent; 251 }; 252 return copyParams; 253 } 254 255 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 256 { 257 const VkCommandBufferBeginInfo info = 258 { 259 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 260 DE_NULL, // const void* pNext; 261 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 262 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 263 }; 264 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info)); 265 } 266 267 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 268 { 269 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 270 } 271 272 void submitCommandsAndWait (const DeviceInterface& vk, 273 const VkDevice device, 274 const VkQueue queue, 275 const VkCommandBuffer commandBuffer) 276 { 277 const VkFenceCreateInfo fenceInfo = 278 { 279 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 280 DE_NULL, // const void* pNext; 281 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags; 282 }; 283 const Unique<VkFence> fence(createFence(vk, device, &fenceInfo)); 284 285 const VkSubmitInfo submitInfo = 286 { 287 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 288 DE_NULL, // const void* pNext; 289 0u, // uint32_t waitSemaphoreCount; 290 DE_NULL, // const VkSemaphore* pWaitSemaphores; 291 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 292 1u, // uint32_t commandBufferCount; 293 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 294 0u, // uint32_t signalSemaphoreCount; 295 DE_NULL, // const VkSemaphore* pSignalSemaphores; 296 }; 297 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 298 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 299 } 300 301 std::string getPrimitiveTopologyShortName (const VkPrimitiveTopology topology) 302 { 303 std::string name(getPrimitiveTopologyName(topology)); 304 return de::toLower(name.substr(22)); 305 } 306 307 DrawState::DrawState(const vk::VkPrimitiveTopology topology_, deUint32 renderWidth_, deUint32 renderHeight_) 308 : topology (topology_) 309 , colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 310 , renderSize (tcu::UVec2(renderWidth_, renderHeight_)) 311 , depthClampEnable (false) 312 , depthTestEnable (false) 313 , depthWriteEnable (false) 314 , compareOp (rr::TESTFUNC_LESS) 315 , depthBoundsTestEnable (false) 316 , blendEnable (false) 317 , lineWidth (1.0) 318 , numPatchControlPoints (0) 319 , numSamples (VK_SAMPLE_COUNT_1_BIT) 320 , sampleShadingEnable (false) 321 { 322 DE_ASSERT(renderSize.x() != 0 && renderSize.y() != 0); 323 } 324 325 ReferenceDrawContext::~ReferenceDrawContext (void) 326 { 327 } 328 329 void ReferenceDrawContext::draw (void) 330 { 331 m_refImage.setStorage(vk::mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y()); 332 tcu::clear(m_refImage.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 333 334 { 335 const rr::Program program(&m_vertexShader, &m_fragmentShader); 336 const rr::MultisamplePixelBufferAccess referenceColorBuffer = rr::MultisamplePixelBufferAccess::fromSinglesampleAccess(m_refImage.getAccess()); 337 const rr::RenderTarget renderTarget(referenceColorBuffer); 338 const rr::RenderState renderState((rr::ViewportState(referenceColorBuffer)), rr::VIEWPORTORIENTATION_UPPER_LEFT); 339 const rr::Renderer renderer; 340 const rr::VertexAttrib vertexAttrib[] = 341 { 342 rr::VertexAttrib(rr::VERTEXATTRIBTYPE_FLOAT, 4, sizeof(tcu::Vec4), 0, &m_drawCallData.vertices[0]) 343 }; 344 345 renderer.draw(rr::DrawCommand( renderState, 346 renderTarget, 347 program, 348 DE_LENGTH_OF_ARRAY(vertexAttrib), 349 &vertexAttrib[0], 350 rr::PrimitiveList(mapVkPrimitiveToRRPrimitive(m_drawState.topology), (int)m_drawCallData.vertices.size(), 0))); 351 352 } 353 354 } 355 356 tcu::ConstPixelBufferAccess ReferenceDrawContext::getColorPixels (void) const 357 { 358 return tcu::ConstPixelBufferAccess( m_refImage.getAccess().getFormat(), 359 m_refImage.getAccess().getWidth(), 360 m_refImage.getAccess().getHeight(), 361 m_refImage.getAccess().getDepth(), 362 m_refImage.getAccess().getDataPtr()); 363 } 364 365 VulkanDrawContext::VulkanDrawContext ( Context& context, 366 const DrawState& drawState, 367 const DrawCallData& drawCallData, 368 const VulkanProgram& vulkanProgram) 369 : DrawContext (drawState, drawCallData) 370 , m_context (context) 371 , m_program (vulkanProgram) 372 { 373 const DeviceInterface& vk = m_context.getDeviceInterface(); 374 const VkDevice device = m_context.getDevice(); 375 Allocator& allocator = m_context.getDefaultAllocator(); 376 VkImageSubresourceRange colorSubresourceRange; 377 Move<VkSampler> sampler; 378 379 // Command buffer 380 { 381 m_cmdPool = makeCommandPool(vk, device, m_context.getUniversalQueueFamilyIndex()); 382 m_cmdBuffer = makeCommandBuffer(vk, device, *m_cmdPool); 383 } 384 385 // Color attachment image 386 { 387 const VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 388 colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 389 const VkImageCreateInfo imageCreateInfo = 390 { 391 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 392 DE_NULL, // const void* pNext; 393 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 394 VK_IMAGE_TYPE_2D, // VkImageType imageType; 395 m_drawState.colorFormat, // VkFormat format; 396 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u), // VkExtent3D extent; 397 1u, // uint32_t mipLevels; 398 1u, // uint32_t arrayLayers; 399 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples; 400 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 401 usage, // VkImageUsageFlags usage; 402 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 403 0u, // uint32_t queueFamilyIndexCount; 404 DE_NULL, // const uint32_t* pQueueFamilyIndices; 405 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 406 }; 407 408 m_colorImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, imageCreateInfo, MemoryRequirement::Any)); 409 m_colorImageView = makeImageView(vk, device, **m_colorImage, VK_IMAGE_VIEW_TYPE_2D, m_drawState.colorFormat, colorSubresourceRange); 410 411 // Buffer to copy attachment data after rendering 412 413 const VkDeviceSize bitmapSize = tcu::getPixelSize(mapVkFormat(m_drawState.colorFormat)) * m_drawState.renderSize.x() * m_drawState.renderSize.y(); 414 m_colorAttachmentBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory( 415 vk, device, allocator, makeBufferCreateInfo(bitmapSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible)); 416 417 { 418 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation(); 419 deMemset(alloc.getHostPtr(), 0, (size_t)bitmapSize); 420 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bitmapSize); 421 } 422 } 423 424 // Vertex buffer 425 { 426 const VkDeviceSize bufferSize = m_drawCallData.vertices.size() * sizeof(m_drawCallData.vertices[0]); 427 m_vertexBuffer = MovePtr<BufferWithMemory>(new BufferWithMemory( 428 vk, device, allocator, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible)); 429 430 const Allocation& alloc = m_vertexBuffer->getAllocation(); 431 deMemcpy(alloc.getHostPtr(), &m_drawCallData.vertices[0], (size_t)bufferSize); 432 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), bufferSize); 433 } 434 435 // bind descriptor sets 436 { 437 if (!vulkanProgram.descriptorSetLayout) 438 m_pipelineLayout = makePipelineLayoutWithoutDescriptors(vk, device); 439 else 440 m_pipelineLayout = makePipelineLayout(vk, device, vulkanProgram.descriptorSetLayout); 441 } 442 443 // Renderpass 444 { 445 std::vector<VkAttachmentDescription> attachmentDescriptions; 446 const VkAttachmentDescription attachDescriptors[] = 447 { 448 { 449 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 450 m_drawState.colorFormat, // VkFormat format; 451 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples; 452 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 453 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 454 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 455 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 456 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 457 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 458 }, 459 { 460 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags 461 m_drawState.depthFormat, // VkFormat format 462 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits samples 463 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp 464 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp 465 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp 466 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp 467 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout 468 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout 469 470 } 471 }; 472 473 const VkAttachmentReference attachmentReferences[] = 474 { 475 { 476 0u, // uint32_t attachment 477 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout 478 }, 479 { 480 1u, // uint32_t attachment 481 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout 482 }, 483 { 484 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 485 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 486 } 487 }; 488 489 attachmentDescriptions.push_back(attachDescriptors[0]); 490 if (!!vulkanProgram.depthImageView) 491 attachmentDescriptions.push_back(attachDescriptors[1]); 492 493 deUint32 depthReferenceNdx = !!vulkanProgram.depthImageView ? 1 : 2; 494 const VkSubpassDescription subpassDescription = 495 { 496 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 497 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 498 0u, // deUint32 inputAttachmentCount; 499 DE_NULL, // const VkAttachmentReference* pInputAttachments; 500 1u, // deUint32 colorAttachmentCount; 501 &attachmentReferences[0], // const VkAttachmentReference* pColorAttachments; 502 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 503 &attachmentReferences[depthReferenceNdx], // const VkAttachmentReference* pDepthStencilAttachment; 504 0u, // deUint32 preserveAttachmentCount; 505 DE_NULL // const deUint32* pPreserveAttachments; 506 }; 507 508 const VkRenderPassCreateInfo renderPassInfo = 509 { 510 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 511 DE_NULL, // const void* pNext; 512 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 513 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount; 514 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments; 515 1u, // deUint32 subpassCount; 516 &subpassDescription, // const VkSubpassDescription* pSubpasses; 517 0u, // deUint32 dependencyCount; 518 DE_NULL // const VkSubpassDependency* pDependencies; 519 }; 520 521 m_renderPass = createRenderPass(vk, device, &renderPassInfo); 522 } 523 524 // Framebuffer 525 { 526 std::vector<VkImageView> attachmentBindInfos; 527 deUint32 numAttachments; 528 attachmentBindInfos.push_back(*m_colorImageView); 529 if (!!vulkanProgram.depthImageView) 530 attachmentBindInfos.push_back(vulkanProgram.depthImageView); 531 532 numAttachments = (deUint32)(attachmentBindInfos.size()); 533 const VkFramebufferCreateInfo framebufferInfo = { 534 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 535 DE_NULL, // const void* pNext; 536 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 537 *m_renderPass, // VkRenderPass renderPass; 538 numAttachments, // uint32_t attachmentCount; 539 &attachmentBindInfos[0], // const VkImageView* pAttachments; 540 m_drawState.renderSize.x(), // uint32_t width; 541 m_drawState.renderSize.y(), // uint32_t height; 542 1u, // uint32_t layers; 543 }; 544 545 m_framebuffer = createFramebuffer(vk, device, &framebufferInfo); 546 } 547 548 // Graphics pipeline 549 { 550 const deUint32 vertexStride = sizeof(Vec4); 551 const VkFormat vertexFormat = VK_FORMAT_R32G32B32A32_SFLOAT; 552 553 DE_ASSERT(m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST || m_drawState.numPatchControlPoints > 0); 554 555 const VkVertexInputBindingDescription bindingDesc = 556 { 557 0u, // uint32_t binding; 558 vertexStride, // uint32_t stride; 559 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 560 }; 561 const VkVertexInputAttributeDescription attributeDesc = 562 { 563 0u, // uint32_t location; 564 0u, // uint32_t binding; 565 vertexFormat, // VkFormat format; 566 0u, // uint32_t offset; 567 }; 568 569 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 570 { 571 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 572 DE_NULL, // const void* pNext; 573 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 574 1u, // uint32_t vertexBindingDescriptionCount; 575 &bindingDesc, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 576 1u, // uint32_t vertexAttributeDescriptionCount; 577 &attributeDesc, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 578 }; 579 580 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 581 { 582 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 583 DE_NULL, // const void* pNext; 584 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 585 m_drawState.topology, // VkPrimitiveTopology topology; 586 VK_FALSE, // VkBool32 primitiveRestartEnable; 587 }; 588 589 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo = 590 { 591 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 592 DE_NULL, // const void* pNext; 593 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 594 m_drawState.numPatchControlPoints, // uint32_t patchControlPoints; 595 }; 596 597 const VkViewport viewport = makeViewport( 598 0.0f, 0.0f, 599 static_cast<float>(m_drawState.renderSize.x()), static_cast<float>(m_drawState.renderSize.y()), 600 0.0f, 1.0f); 601 602 const VkRect2D scissor = { 603 makeOffset2D(0, 0), 604 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()), 605 }; 606 607 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 608 { 609 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 610 DE_NULL, // const void* pNext; 611 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 612 1u, // uint32_t viewportCount; 613 &viewport, // const VkViewport* pViewports; 614 1u, // uint32_t scissorCount; 615 &scissor, // const VkRect2D* pScissors; 616 }; 617 618 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 619 { 620 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 621 DE_NULL, // const void* pNext; 622 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 623 m_drawState.depthClampEnable, // VkBool32 depthClampEnable; 624 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 625 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 626 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 627 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 628 VK_FALSE, // VkBool32 depthBiasEnable; 629 0.0f, // float depthBiasConstantFactor; 630 0.0f, // float depthBiasClamp; 631 0.0f, // float depthBiasSlopeFactor; 632 m_drawState.lineWidth, // float lineWidth; 633 }; 634 635 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 636 { 637 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 638 DE_NULL, // const void* pNext; 639 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 640 (VkSampleCountFlagBits)m_drawState.numSamples, // VkSampleCountFlagBits rasterizationSamples; 641 m_drawState.sampleShadingEnable ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable; 642 m_drawState.sampleShadingEnable ? 1.0f : 0.0f, // float minSampleShading; 643 DE_NULL, // const VkSampleMask* pSampleMask; 644 VK_FALSE, // VkBool32 alphaToCoverageEnable; 645 VK_FALSE // VkBool32 alphaToOneEnable; 646 }; 647 648 const VkStencilOpState stencilOpState = makeStencilOpState( 649 VK_STENCIL_OP_KEEP, // stencil fail 650 VK_STENCIL_OP_KEEP, // depth & stencil pass 651 VK_STENCIL_OP_KEEP, // depth only fail 652 VK_COMPARE_OP_NEVER, // compare op 653 0u, // compare mask 654 0u, // write mask 655 0u); // reference 656 657 if (m_drawState.depthBoundsTestEnable && !context.getDeviceFeatures().depthBounds) 658 TCU_THROW(NotSupportedError, "depthBounds not supported"); 659 660 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 661 { 662 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 663 DE_NULL, // const void* pNext; 664 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 665 m_drawState.depthTestEnable, // VkBool32 depthTestEnable; 666 m_drawState.depthWriteEnable, // VkBool32 depthWriteEnable; 667 mapCompareOp(m_drawState.compareOp), // VkCompareOp depthCompareOp; 668 m_drawState.depthBoundsTestEnable, // VkBool32 depthBoundsTestEnable 669 VK_FALSE, // VkBool32 stencilTestEnable; 670 stencilOpState, // VkStencilOpState front; 671 stencilOpState, // VkStencilOpState back; 672 0.0f, // float minDepthBounds; 673 1.0f, // float maxDepthBounds; 674 }; 675 676 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 677 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 678 { 679 m_drawState.blendEnable, // VkBool32 blendEnable; 680 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor; 681 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 682 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 683 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor; 684 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 685 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 686 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 687 }; 688 689 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 690 { 691 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 692 DE_NULL, // const void* pNext; 693 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 694 VK_FALSE, // VkBool32 logicOpEnable; 695 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 696 1u, // deUint32 attachmentCount; 697 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 698 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 699 }; 700 701 // Create shader stages 702 703 std::vector<VkPipelineShaderStageCreateInfo> shaderStages; 704 VkShaderStageFlags stageFlags = (VkShaderStageFlags)0; 705 706 DE_ASSERT(m_program.shaders.size() <= MAX_NUM_SHADER_MODULES); 707 for (deUint32 shaderNdx = 0; shaderNdx < m_program.shaders.size(); ++shaderNdx) 708 { 709 m_shaderModules[shaderNdx] = createShaderModule(vk, device, *m_program.shaders[shaderNdx].binary, (VkShaderModuleCreateFlags)0); 710 711 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo = 712 { 713 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 714 DE_NULL, // const void* pNext; 715 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 716 m_program.shaders[shaderNdx].stage, // VkShaderStageFlagBits stage; 717 *m_shaderModules[shaderNdx], // VkShaderModule module; 718 "main", // const char* pName; 719 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 720 }; 721 722 shaderStages.push_back(pipelineShaderStageInfo); 723 stageFlags |= m_program.shaders[shaderNdx].stage; 724 } 725 726 DE_ASSERT( 727 (m_drawState.topology != VK_PRIMITIVE_TOPOLOGY_PATCH_LIST) || 728 (stageFlags & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))); 729 730 const bool tessellationEnabled = (m_drawState.topology == VK_PRIMITIVE_TOPOLOGY_PATCH_LIST); 731 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 732 { 733 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 734 DE_NULL, // const void* pNext; 735 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 736 static_cast<deUint32>(shaderStages.size()), // deUint32 stageCount; 737 &shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages; 738 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 739 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 740 (tessellationEnabled ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState; 741 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 742 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 743 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 744 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 745 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 746 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 747 *m_pipelineLayout, // VkPipelineLayout layout; 748 *m_renderPass, // VkRenderPass renderPass; 749 0u, // deUint32 subpass; 750 DE_NULL, // VkPipeline basePipelineHandle; 751 0, // deInt32 basePipelineIndex; 752 }; 753 754 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 755 } 756 757 // Record commands 758 { 759 const VkDeviceSize zeroOffset = 0ull; 760 761 beginCommandBuffer(vk, *m_cmdBuffer); 762 if (!!vulkanProgram.descriptorSet) 763 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u, &vulkanProgram.descriptorSet, 0u, DE_NULL); 764 765 // Begin render pass 766 { 767 std::vector<VkClearValue> clearValues; 768 769 clearValues.push_back(makeClearValueColor(Vec4(0.0f, 0.0f, 0.0f, 1.0f))); 770 if (!!vulkanProgram.depthImageView) 771 clearValues.push_back(makeClearValueDepthStencil(0.0, 0)); 772 773 const VkRect2D renderArea = 774 { 775 makeOffset2D(0, 0), 776 makeExtent2D(m_drawState.renderSize.x(), m_drawState.renderSize.y()) 777 }; 778 779 const VkRenderPassBeginInfo renderPassBeginInfo = { 780 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 781 DE_NULL, // const void* pNext; 782 *m_renderPass, // VkRenderPass renderPass; 783 *m_framebuffer, // VkFramebuffer framebuffer; 784 renderArea, // VkRect2D renderArea; 785 static_cast<deUint32>(clearValues.size()), // uint32_t clearValueCount; 786 &clearValues[0], // const VkClearValue* pClearValues; 787 }; 788 789 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 790 } 791 792 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 793 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0u, 1u, &(**m_vertexBuffer), &zeroOffset); 794 795 vk.cmdDraw(*m_cmdBuffer, static_cast<deUint32>(m_drawCallData.vertices.size()), 1u, 0u, 0u); 796 vk.cmdEndRenderPass(*m_cmdBuffer); 797 798 // Barrier: draw -> copy from image 799 { 800 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier( 801 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 802 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 803 **m_colorImage, colorSubresourceRange); 804 805 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 806 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier); 807 } 808 809 // Resolve multisample image 810 { 811 if (m_drawState.numSamples != VK_SAMPLE_COUNT_1_BIT) 812 { 813 const VkImageResolve imageResolve = 814 { 815 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), 816 { 0, 0, 0}, 817 makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), 818 { 0, 0, 0}, 819 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u) 820 }; 821 822 const VkImageCreateInfo resolveImageCreateInfo = 823 { 824 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 825 DE_NULL, // const void* pNext 826 (VkImageCreateFlags)0, // VkImageCreateFlags flags 827 VK_IMAGE_TYPE_2D, // VkImageType imageType 828 m_drawState.colorFormat, // VkFormat format 829 makeExtent3D(m_drawState.renderSize.x(), // VkExtent3D extent; 830 m_drawState.renderSize.y(), 1u), 831 1u, // uint32_t mipLevels 832 1u, // uint32_t arrayLayers 833 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples 834 VK_IMAGE_TILING_OPTIMAL, // VkImaageTiling tiling 835 VK_IMAGE_USAGE_TRANSFER_DST_BIT | // VkImageUsageFlags usage 836 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 837 VK_SHARING_MODE_EXCLUSIVE, // VkSharingModeExclusive sharingMode 838 0u, // uint32_t queueFamilyIndexCount 839 DE_NULL, // const uint32_t* pQueueFamilyIndices 840 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 841 }; 842 843 m_resolveImage = MovePtr<ImageWithMemory>(new ImageWithMemory(vk, device, allocator, resolveImageCreateInfo, MemoryRequirement::Any)); 844 845 const VkImageMemoryBarrier resolveBarrier = makeImageMemoryBarrier( 846 0u, VK_ACCESS_TRANSFER_READ_BIT, 847 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 848 **m_resolveImage, colorSubresourceRange); 849 850 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 851 0u, DE_NULL, 0u, DE_NULL, 1u, &resolveBarrier); 852 853 vk.cmdResolveImage(*m_cmdBuffer, **m_colorImage, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 854 **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, &imageResolve); 855 856 const VkImageMemoryBarrier barrier = makeImageMemoryBarrier( 857 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 858 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 859 **m_resolveImage, colorSubresourceRange); 860 861 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 862 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier); 863 } 864 else 865 m_resolveImage = m_colorImage; 866 867 const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u), 868 makeExtent3D(m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u)); 869 vk.cmdCopyImageToBuffer(*m_cmdBuffer, **m_resolveImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, **m_colorAttachmentBuffer, 1u, ©Region); 870 } 871 872 // Barrier: copy to buffer -> host read 873 { 874 const VkBufferMemoryBarrier barrier = makeBufferMemoryBarrier( 875 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, 876 **m_colorAttachmentBuffer, 0ull, VK_WHOLE_SIZE); 877 878 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 879 0u, DE_NULL, 1u, &barrier, 0u, DE_NULL); 880 } 881 882 endCommandBuffer(vk, *m_cmdBuffer); 883 } 884 } 885 886 VulkanDrawContext::~VulkanDrawContext (void) 887 { 888 } 889 890 void VulkanDrawContext::draw (void) 891 { 892 const DeviceInterface& vk = m_context.getDeviceInterface(); 893 const VkDevice device = m_context.getDevice(); 894 const VkQueue queue = m_context.getUniversalQueue(); 895 tcu::TestLog& log = m_context.getTestContext().getLog(); 896 897 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer); 898 899 log << tcu::LogImageSet("attachments", "") << tcu::LogImage("color0", "", getColorPixels()) << tcu::TestLog::EndImageSet; 900 } 901 902 tcu::ConstPixelBufferAccess VulkanDrawContext::getColorPixels (void) const 903 { 904 const DeviceInterface& vk = m_context.getDeviceInterface(); 905 const VkDevice device = m_context.getDevice(); 906 907 const Allocation& alloc = m_colorAttachmentBuffer->getAllocation(); 908 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), VK_WHOLE_SIZE); 909 910 return tcu::ConstPixelBufferAccess(mapVkFormat(m_drawState.colorFormat), m_drawState.renderSize.x(), m_drawState.renderSize.y(), 1u, alloc.getHostPtr()); 911 } 912 } // drawutil 913 } // vkt 914