1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * Copyright (c) 2015 The Khronos Group 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 Early fragment tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktPipelineEarlyFragmentTests.hpp" 26#include "vktTestCaseUtil.hpp" 27 28#include "vkDefs.hpp" 29#include "vkRef.hpp" 30#include "vkRefUtil.hpp" 31#include "vkPlatform.hpp" 32#include "vkPrograms.hpp" 33#include "vkMemUtil.hpp" 34#include "vkBuilderUtil.hpp" 35#include "vkStrUtil.hpp" 36#include "vkTypeUtil.hpp" 37#include "vkQueryUtil.hpp" 38#include "vkImageUtil.hpp" 39 40#include "deUniquePtr.hpp" 41#include "deStringUtil.hpp" 42 43#include <string> 44 45using namespace vk; 46 47namespace vkt 48{ 49namespace pipeline 50{ 51namespace 52{ 53 54// \note Some utility functions are general, but others are custom tailored to this test. 55 56class Buffer 57{ 58public: 59 Buffer (const DeviceInterface& vk, 60 const VkDevice device, 61 Allocator& allocator, 62 const VkBufferCreateInfo& bufferCreateInfo, 63 const MemoryRequirement memoryRequirement) 64 65 : m_buffer (createBuffer(vk, device, &bufferCreateInfo)) 66 , m_allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement)) 67 { 68 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset())); 69 } 70 71 const VkBuffer& get (void) const { return *m_buffer; } 72 const VkBuffer& operator* (void) const { return get(); } 73 Allocation& getAllocation (void) const { return *m_allocation; } 74 75private: 76 const Unique<VkBuffer> m_buffer; 77 const de::UniquePtr<Allocation> m_allocation; 78 79 // "deleted" 80 Buffer (const Buffer&); 81 Buffer& operator= (const Buffer&); 82}; 83 84class Image 85{ 86public: 87 Image (const DeviceInterface& vk, 88 const VkDevice device, 89 Allocator& allocator, 90 const VkImageCreateInfo& imageCreateInfo, 91 const MemoryRequirement memoryRequirement) 92 93 : m_image (createImage(vk, device, &imageCreateInfo)) 94 , m_allocation (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement)) 95 { 96 VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset())); 97 } 98 99 const VkImage& get (void) const { return *m_image; } 100 const VkImage& operator* (void) const { return get(); } 101 Allocation& getAllocation (void) const { return *m_allocation; } 102 103private: 104 const Unique<VkImage> m_image; 105 const de::UniquePtr<Allocation> m_allocation; 106 107 // "deleted" 108 Image (const Image&); 109 Image& operator= (const Image&); 110}; 111 112Move<VkImageView> makeImageView (const DeviceInterface& vk, 113 const VkDevice vkDevice, 114 const VkImage image, 115 const VkImageViewType imageViewType, 116 const VkFormat format, 117 const VkImageSubresourceRange subresourceRange) 118{ 119 const VkImageViewCreateInfo imageViewParams = 120 { 121 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 122 DE_NULL, // const void* pNext; 123 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 124 image, // VkImage image; 125 imageViewType, // VkImageViewType viewType; 126 format, // VkFormat format; 127 makeComponentMappingRGBA(), // VkComponentMapping components; 128 subresourceRange, // VkImageSubresourceRange subresourceRange; 129 }; 130 return createImageView(vk, vkDevice, &imageViewParams); 131} 132 133VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 134 const VkBufferUsageFlags usage) 135{ 136 const VkBufferCreateInfo bufferCreateInfo = 137 { 138 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 139 DE_NULL, // const void* pNext; 140 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 141 bufferSize, // VkDeviceSize size; 142 usage, // VkBufferUsageFlags usage; 143 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 144 0u, // deUint32 queueFamilyIndexCount; 145 DE_NULL, // const deUint32* pQueueFamilyIndices; 146 }; 147 return bufferCreateInfo; 148} 149 150Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 151 const VkDevice device, 152 const VkDescriptorPool descriptorPool, 153 const VkDescriptorSetLayout setLayout) 154{ 155 const VkDescriptorSetAllocateInfo allocateParams = 156 { 157 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 158 DE_NULL, // const void* pNext; 159 descriptorPool, // VkDescriptorPool descriptorPool; 160 1u, // deUint32 setLayoutCount; 161 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 162 }; 163 return allocateDescriptorSet(vk, device, &allocateParams); 164} 165 166Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 167 const VkDevice device, 168 const VkDescriptorSetLayout descriptorSetLayout) 169{ 170 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 171 { 172 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 173 DE_NULL, // const void* pNext; 174 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 175 1u, // deUint32 setLayoutCount; 176 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 177 0u, // deUint32 pushConstantRangeCount; 178 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 179 }; 180 return createPipelineLayout(vk, device, &pipelineLayoutParams); 181} 182 183Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex) 184{ 185 const VkCommandPoolCreateInfo commandPoolParams = 186 { 187 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType; 188 DE_NULL, // const void* pNext; 189 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags; 190 queueFamilyIndex, // deUint32 queueFamilyIndex; 191 }; 192 return createCommandPool(vk, device, &commandPoolParams); 193} 194 195Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 196{ 197 const VkCommandBufferAllocateInfo bufferAllocateParams = 198 { 199 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType; 200 DE_NULL, // const void* pNext; 201 commandPool, // VkCommandPool commandPool; 202 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level; 203 1u, // deUint32 bufferCount; 204 }; 205 return allocateCommandBuffer(vk, device, &bufferAllocateParams); 206} 207 208void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 209{ 210 const VkCommandBufferBeginInfo commandBufBeginParams = 211 { 212 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 213 DE_NULL, // const void* pNext; 214 (VkCommandBufferUsageFlags)0, // VkCommandBufferUsageFlags flags; 215 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 216 }; 217 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &commandBufBeginParams)); 218} 219 220void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 221{ 222 VK_CHECK(vk.endCommandBuffer(commandBuffer)); 223} 224 225void submitCommandsAndWait (const DeviceInterface& vk, 226 const VkDevice device, 227 const VkQueue queue, 228 const VkCommandBuffer commandBuffer) 229{ 230 const VkFenceCreateInfo fenceParams = 231 { 232 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType; 233 DE_NULL, // const void* pNext; 234 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags; 235 }; 236 const Unique<VkFence> fence(createFence(vk, device, &fenceParams)); 237 238 const VkSubmitInfo submitInfo = 239 { 240 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 241 DE_NULL, // const void* pNext; 242 0u, // deUint32 waitSemaphoreCount; 243 DE_NULL, // const VkSemaphore* pWaitSemaphores; 244 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 245 1u, // deUint32 commandBufferCount; 246 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 247 0u, // deUint32 signalSemaphoreCount; 248 DE_NULL, // const VkSemaphore* pSignalSemaphores; 249 }; 250 251 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 252 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 253} 254 255VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 256 const VkAccessFlags dstAccessMask, 257 const VkImageLayout oldLayout, 258 const VkImageLayout newLayout, 259 const VkImage image, 260 const VkImageSubresourceRange subresourceRange) 261{ 262 const VkImageMemoryBarrier barrier = 263 { 264 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 265 DE_NULL, // const void* pNext; 266 srcAccessMask, // VkAccessFlags outputMask; 267 dstAccessMask, // VkAccessFlags inputMask; 268 oldLayout, // VkImageLayout oldLayout; 269 newLayout, // VkImageLayout newLayout; 270 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 271 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 272 image, // VkImage image; 273 subresourceRange, // VkImageSubresourceRange subresourceRange; 274 }; 275 return barrier; 276} 277 278VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 279 const VkAccessFlags dstAccessMask, 280 const VkBuffer buffer, 281 const VkDeviceSize offset, 282 const VkDeviceSize bufferSizeBytes) 283{ 284 const VkBufferMemoryBarrier barrier = 285 { 286 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 287 DE_NULL, // const void* pNext; 288 srcAccessMask, // VkAccessFlags srcAccessMask; 289 dstAccessMask, // VkAccessFlags dstAccessMask; 290 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 291 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 292 buffer, // VkBuffer buffer; 293 offset, // VkDeviceSize offset; 294 bufferSizeBytes, // VkDeviceSize size; 295 }; 296 return barrier; 297} 298 299//! Basic 2D image. 300inline VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage) 301{ 302 const VkImageCreateInfo imageParams = 303 { 304 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 305 DE_NULL, // const void* pNext; 306 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 307 VK_IMAGE_TYPE_2D, // VkImageType imageType; 308 format, // VkFormat format; 309 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; 310 1u, // deUint32 mipLevels; 311 1u, // deUint32 arrayLayers; 312 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 313 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 314 usage, // VkImageUsageFlags usage; 315 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 316 0u, // deUint32 queueFamilyIndexCount; 317 DE_NULL, // const deUint32* pQueueFamilyIndices; 318 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 319 }; 320 return imageParams; 321} 322 323void beginRenderPass (const DeviceInterface& vk, 324 const VkCommandBuffer commandBuffer, 325 const VkRenderPass renderPass, 326 const VkFramebuffer framebuffer, 327 const VkRect2D& renderArea, 328 const tcu::Vec4& clearColor, 329 const float clearDepth, 330 const deUint32 clearStencil) 331{ 332 const VkClearValue clearValues[] = 333 { 334 makeClearValueColor(clearColor), // attachment 0 335 makeClearValueDepthStencil(clearDepth, clearStencil), // attachment 1 336 }; 337 338 const VkRenderPassBeginInfo renderPassBeginInfo = { 339 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 340 DE_NULL, // const void* pNext; 341 renderPass, // VkRenderPass renderPass; 342 framebuffer, // VkFramebuffer framebuffer; 343 renderArea, // VkRect2D renderArea; 344 DE_LENGTH_OF_ARRAY(clearValues), // uint32_t clearValueCount; 345 clearValues, // const VkClearValue* pClearValues; 346 }; 347 348 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 349} 350 351void endRenderPass (const DeviceInterface& vk, 352 const VkCommandBuffer commandBuffer) 353{ 354 vk.cmdEndRenderPass(commandBuffer); 355} 356 357Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 358 const VkDevice device, 359 const VkFormat colorFormat, 360 const bool useDepthStencilAttachment, 361 const VkFormat depthStencilFormat) 362{ 363 const VkAttachmentDescription attachments[] = 364 { 365 // color 366 { 367 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 368 colorFormat, // VkFormat format; 369 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 370 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 371 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 372 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 373 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 374 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 375 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 376 }, 377 // depth/stencil 378 { 379 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 380 depthStencilFormat, // VkFormat format; 381 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 382 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 383 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 384 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 385 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp; 386 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 387 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 388 } 389 }; 390 391 const VkAttachmentReference unusedAttachmentReference = 392 { 393 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 394 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 395 }; 396 397 const VkAttachmentReference colorAttachmentReference = 398 { 399 0u, // deUint32 attachment; 400 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 401 }; 402 403 const VkAttachmentReference depthStencilAttachmentReference = 404 { 405 1u, // deUint32 attachment; 406 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; 407 }; 408 409 const VkAttachmentReference* pDepthStencilAttachment = (useDepthStencilAttachment ? &depthStencilAttachmentReference : &unusedAttachmentReference); 410 411 const VkSubpassDescription subpassDescription = 412 { 413 0u, // VkSubpassDescriptionFlags flags; 414 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 415 0u, // deUint32 inputAttachmentCount; 416 DE_NULL, // const VkAttachmentReference* pInputAttachments; 417 1u, // deUint32 colorAttachmentCount; 418 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 419 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 420 pDepthStencilAttachment, // const VkAttachmentReference* pDepthStencilAttachment; 421 0u, // deUint32 preserveAttachmentCount; 422 DE_NULL // const deUint32* pPreserveAttachments; 423 }; 424 425 const VkRenderPassCreateInfo renderPassInfo = 426 { 427 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 428 DE_NULL, // const void* pNext; 429 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 430 (useDepthStencilAttachment ? 2u : 1u), // deUint32 attachmentCount; 431 attachments, // const VkAttachmentDescription* pAttachments; 432 1u, // deUint32 subpassCount; 433 &subpassDescription, // const VkSubpassDescription* pSubpasses; 434 0u, // deUint32 dependencyCount; 435 DE_NULL // const VkSubpassDependency* pDependencies; 436 }; 437 438 return createRenderPass(vk, device, &renderPassInfo); 439} 440 441Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 442 const VkDevice device, 443 const VkRenderPass renderPass, 444 const deUint32 attachmentCount, 445 const VkImageView* pAttachments, 446 const tcu::IVec2 size) 447{ 448 const VkFramebufferCreateInfo framebufferInfo = { 449 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 450 DE_NULL, // const void* pNext; 451 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 452 renderPass, // VkRenderPass renderPass; 453 attachmentCount, // uint32_t attachmentCount; 454 pAttachments, // const VkImageView* pAttachments; 455 static_cast<deUint32>(size.x()), // uint32_t width; 456 static_cast<deUint32>(size.y()), // uint32_t height; 457 1u, // uint32_t layers; 458 }; 459 460 return createFramebuffer(vk, device, &framebufferInfo); 461} 462 463Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk, 464 const VkDevice device, 465 const VkPipelineLayout pipelineLayout, 466 const VkRenderPass renderPass, 467 const VkShaderModule vertexModule, 468 const VkShaderModule fragmentModule, 469 const tcu::IVec2& renderSize, 470 const bool enableDepthTest, 471 const bool enableStencilTest) 472{ 473 const VkVertexInputBindingDescription vertexInputBindingDescription = 474 { 475 0u, // uint32_t binding; 476 sizeof(tcu::Vec4), // uint32_t stride; // Vertex is a 4-element vector XYZW, position only 477 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 478 }; 479 480 const VkVertexInputAttributeDescription vertexInputAttributeDescription = 481 { 482 0u, // uint32_t location; 483 0u, // uint32_t binding; 484 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 485 0u, // uint32_t offset; 486 }; 487 488 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 489 { 490 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 491 DE_NULL, // const void* pNext; 492 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 493 1u, // uint32_t vertexBindingDescriptionCount; 494 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 495 1u, // uint32_t vertexAttributeDescriptionCount; 496 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 497 }; 498 499 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 500 { 501 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 502 DE_NULL, // const void* pNext; 503 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 504 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 505 VK_FALSE, // VkBool32 primitiveRestartEnable; 506 }; 507 508 const VkViewport viewport = makeViewport( 509 0.0f, 0.0f, 510 static_cast<float>(renderSize.x()), static_cast<float>(renderSize.y()), 511 0.0f, 1.0f); 512 513 const VkRect2D scissor = { 514 makeOffset2D(0, 0), 515 makeExtent2D(renderSize.x(), renderSize.y()), 516 }; 517 518 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 519 { 520 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 521 DE_NULL, // const void* pNext; 522 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 523 1u, // uint32_t viewportCount; 524 &viewport, // const VkViewport* pViewports; 525 1u, // uint32_t scissorCount; 526 &scissor, // const VkRect2D* pScissors; 527 }; 528 529 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 530 { 531 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 532 DE_NULL, // const void* pNext; 533 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 534 VK_FALSE, // VkBool32 depthClampEnable; 535 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 536 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 537 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 538 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 539 VK_FALSE, // VkBool32 depthBiasEnable; 540 0.0f, // float depthBiasConstantFactor; 541 0.0f, // float depthBiasClamp; 542 0.0f, // float depthBiasSlopeFactor; 543 1.0f, // float lineWidth; 544 }; 545 546 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 547 { 548 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 549 DE_NULL, // const void* pNext; 550 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 551 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 552 VK_FALSE, // VkBool32 sampleShadingEnable; 553 0.0f, // float minSampleShading; 554 DE_NULL, // const VkSampleMask* pSampleMask; 555 VK_FALSE, // VkBool32 alphaToCoverageEnable; 556 VK_FALSE // VkBool32 alphaToOneEnable; 557 }; 558 559 const VkStencilOpState stencilOpState = makeStencilOpState( 560 VK_STENCIL_OP_KEEP, // stencil fail 561 VK_STENCIL_OP_KEEP, // depth & stencil pass 562 VK_STENCIL_OP_KEEP, // depth only fail 563 VK_COMPARE_OP_EQUAL, // compare op 564 1u, // compare mask 565 1u, // write mask 566 1u); // reference 567 568 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 569 { 570 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 571 DE_NULL, // const void* pNext; 572 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 573 enableDepthTest, // VkBool32 depthTestEnable; 574 VK_TRUE, // VkBool32 depthWriteEnable; 575 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 576 VK_FALSE, // VkBool32 depthBoundsTestEnable; 577 enableStencilTest, // VkBool32 stencilTestEnable; 578 stencilOpState, // VkStencilOpState front; 579 stencilOpState, // VkStencilOpState back; 580 0.0f, // float minDepthBounds; 581 1.0f, // float maxDepthBounds; 582 }; 583 584 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 585 // Number of blend attachments must equal the number of color attachments. 586 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 587 { 588 VK_FALSE, // VkBool32 blendEnable; 589 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 590 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 591 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 592 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 593 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 594 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 595 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 596 }; 597 598 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 599 { 600 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 601 DE_NULL, // const void* pNext; 602 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 603 VK_FALSE, // VkBool32 logicOpEnable; 604 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 605 1u, // deUint32 attachmentCount; 606 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 607 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 608 }; 609 610 const VkPipelineShaderStageCreateInfo pShaderStages[] = 611 { 612 { 613 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 614 DE_NULL, // const void* pNext; 615 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 616 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 617 vertexModule, // VkShaderModule module; 618 "main", // const char* pName; 619 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 620 }, 621 { 622 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 623 DE_NULL, // const void* pNext; 624 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 625 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 626 fragmentModule, // VkShaderModule module; 627 "main", // const char* pName; 628 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo; 629 } 630 }; 631 632 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 633 { 634 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 635 DE_NULL, // const void* pNext; 636 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 637 DE_LENGTH_OF_ARRAY(pShaderStages), // deUint32 stageCount; 638 pShaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 639 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 640 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 641 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 642 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 643 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 644 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 645 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 646 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 647 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 648 pipelineLayout, // VkPipelineLayout layout; 649 renderPass, // VkRenderPass renderPass; 650 0u, // deUint32 subpass; 651 DE_NULL, // VkPipeline basePipelineHandle; 652 0, // deInt32 basePipelineIndex; 653 }; 654 655 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 656} 657 658VkBufferImageCopy makeBufferImageCopy (const VkImageAspectFlags aspectFlags, const tcu::IVec2& renderSize) 659{ 660 const VkBufferImageCopy copyParams = 661 { 662 0ull, // VkDeviceSize bufferOffset; 663 0u, // deUint32 bufferRowLength; 664 0u, // deUint32 bufferImageHeight; 665 makeImageSubresourceLayers(aspectFlags, 0u, 0u, 1u), // VkImageSubresourceLayers imageSubresource; 666 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset; 667 makeExtent3D(renderSize.x(), renderSize.y(), 1u), // VkExtent3D imageExtent; 668 }; 669 return copyParams; 670} 671 672void commandClearStencilAttachment (const DeviceInterface& vk, 673 const VkCommandBuffer commandBuffer, 674 const VkOffset2D& offset, 675 const VkExtent2D& extent, 676 const deUint32 clearValue) 677{ 678 const VkClearAttachment stencilAttachment = 679 { 680 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask; 681 0u, // uint32_t colorAttachment; 682 makeClearValueDepthStencil(0.0f, clearValue), // VkClearValue clearValue; 683 }; 684 685 const VkClearRect rect = 686 { 687 { offset, extent }, // VkRect2D rect; 688 0u, // uint32_t baseArrayLayer; 689 1u, // uint32_t layerCount; 690 }; 691 692 vk.cmdClearAttachments(commandBuffer, 1u, &stencilAttachment, 1u, &rect); 693} 694 695VkImageAspectFlags getImageAspectFlags (const VkFormat format) 696{ 697 const tcu::TextureFormat tcuFormat = mapVkFormat(format); 698 699 if (tcuFormat.order == tcu::TextureFormat::DS) return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 700 else if (tcuFormat.order == tcu::TextureFormat::D) return VK_IMAGE_ASPECT_DEPTH_BIT; 701 else if (tcuFormat.order == tcu::TextureFormat::S) return VK_IMAGE_ASPECT_STENCIL_BIT; 702 703 DE_ASSERT(false); 704 return 0u; 705} 706 707bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, const VkPhysicalDevice device, const VkFormat format) 708{ 709 VkFormatProperties formatProps; 710 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 711 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; 712} 713 714VkFormat pickSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, 715 const VkPhysicalDevice device, 716 const deUint32 numFormats, 717 const VkFormat* pFormats) 718{ 719 for (deUint32 i = 0; i < numFormats; ++i) 720 if (isSupportedDepthStencilFormat(instanceInterface, device, pFormats[i])) 721 return pFormats[i]; 722 return VK_FORMAT_UNDEFINED; 723} 724 725enum Flags 726{ 727 FLAG_TEST_DEPTH = 1u << 0, 728 FLAG_TEST_STENCIL = 1u << 1, 729 FLAG_DONT_USE_TEST_ATTACHMENT = 1u << 2, 730 FLAG_DONT_USE_EARLY_FRAGMENT_TESTS = 1u << 3, 731}; 732 733class EarlyFragmentTest : public TestCase 734{ 735public: 736 EarlyFragmentTest (tcu::TestContext& testCtx, 737 const std::string name, 738 const deUint32 flags); 739 740 void initPrograms (SourceCollections& programCollection) const; 741 TestInstance* createInstance (Context& context) const; 742 743private: 744 const deUint32 m_flags; 745}; 746 747EarlyFragmentTest::EarlyFragmentTest (tcu::TestContext& testCtx, const std::string name, const deUint32 flags) 748 : TestCase (testCtx, name, "") 749 , m_flags (flags) 750{ 751} 752 753void EarlyFragmentTest::initPrograms (SourceCollections& programCollection) const 754{ 755 // Vertex 756 { 757 std::ostringstream src; 758 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" 759 << "\n" 760 << "layout(location = 0) in highp vec4 position;\n" 761 << "\n" 762 << "void main (void)\n" 763 << "{\n" 764 << " gl_Position = position;\n" 765 << "}\n"; 766 767 programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); 768 } 769 770 // Fragment 771 { 772 const bool useEarlyTests = (m_flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0; 773 std::ostringstream src; 774 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_440) << "\n" 775 << "\n" 776 << (useEarlyTests ? "layout(early_fragment_tests) in;\n" : "") 777 << "layout(location = 0) out highp vec4 fragColor;\n" 778 << "\n" 779 << "layout(binding = 0) coherent buffer Output {\n" 780 << " uint result;\n" 781 << "} sb_out;\n" 782 << "\n" 783 << "void main (void)\n" 784 << "{\n" 785 << " atomicAdd(sb_out.result, 1u);\n" 786 << " fragColor = vec4(1.0, 1.0, 0.0, 1.0);\n" 787 << "}\n"; 788 789 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); 790 } 791} 792 793class EarlyFragmentTestInstance : public TestInstance 794{ 795public: 796 EarlyFragmentTestInstance (Context& context, const deUint32 flags); 797 798 tcu::TestStatus iterate (void); 799 800private: 801 enum TestMode 802 { 803 MODE_INVALID, 804 MODE_DEPTH, 805 MODE_STENCIL, 806 }; 807 808 const TestMode m_testMode; 809 const bool m_useTestAttachment; 810 const bool m_useEarlyTests; 811}; 812 813EarlyFragmentTestInstance::EarlyFragmentTestInstance (Context& context, const deUint32 flags) 814 : TestInstance (context) 815 , m_testMode (flags & FLAG_TEST_DEPTH ? MODE_DEPTH : 816 flags & FLAG_TEST_STENCIL ? MODE_STENCIL : MODE_INVALID) 817 , m_useTestAttachment ((flags & FLAG_DONT_USE_TEST_ATTACHMENT) == 0) 818 , m_useEarlyTests ((flags & FLAG_DONT_USE_EARLY_FRAGMENT_TESTS) == 0) 819{ 820 DE_ASSERT(m_testMode != MODE_INVALID); 821} 822 823tcu::TestStatus EarlyFragmentTestInstance::iterate (void) 824{ 825 const DeviceInterface& vk = m_context.getDeviceInterface(); 826 const InstanceInterface& vki = m_context.getInstanceInterface(); 827 const VkDevice device = m_context.getDevice(); 828 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice(); 829 const VkQueue queue = m_context.getUniversalQueue(); 830 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 831 Allocator& allocator = m_context.getDefaultAllocator(); 832 833 // Color attachment 834 835 const tcu::IVec2 renderSize = tcu::IVec2(32, 32); 836 const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; 837 const VkImageSubresourceRange colorSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 838 const Image colorImage (vk, device, allocator, makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT), MemoryRequirement::Any); 839 const Unique<VkImageView> colorImageView (makeImageView(vk, device, *colorImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorSubresourceRange)); 840 841 // Test attachment (depth or stencil) 842 static const VkFormat stencilFormats[] = 843 { 844 // One of the following formats must be supported, as per spec requirement. 845 VK_FORMAT_S8_UINT, 846 VK_FORMAT_D16_UNORM_S8_UINT, 847 VK_FORMAT_D24_UNORM_S8_UINT, 848 VK_FORMAT_D32_SFLOAT_S8_UINT, 849 }; 850 851 const VkFormat testFormat = (m_testMode == MODE_STENCIL ? pickSupportedDepthStencilFormat(vki, physDevice, DE_LENGTH_OF_ARRAY(stencilFormats), stencilFormats) 852 : VK_FORMAT_D16_UNORM); // spec requires this format to be supported 853 if (testFormat == VK_FORMAT_UNDEFINED) 854 return tcu::TestStatus::fail("Required depth/stencil format not supported"); 855 856 if (m_useTestAttachment) 857 m_context.getTestContext().getLog() << tcu::TestLog::Message << "Using depth/stencil format " << getFormatName(testFormat) << tcu::TestLog::EndMessage; 858 859 const VkImageSubresourceRange testSubresourceRange = makeImageSubresourceRange(getImageAspectFlags(testFormat), 0u, 1u, 0u, 1u); 860 const Image testImage (vk, device, allocator, makeImageCreateInfo(renderSize, testFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT), MemoryRequirement::Any); 861 const Unique<VkImageView> testImageView (makeImageView(vk, device, *testImage, VK_IMAGE_VIEW_TYPE_2D, testFormat, testSubresourceRange)); 862 const VkImageView attachmentImages[] = { *colorImageView, *testImageView }; 863 const deUint32 numUsedAttachmentImages = (m_useTestAttachment ? 2u : 1u); 864 865 // Vertex buffer 866 867 const deUint32 numVertices = 6; 868 const VkDeviceSize vertexBufferSizeBytes = sizeof(tcu::Vec4) * numVertices; 869 const Buffer vertexBuffer (vk, device, allocator, makeBufferCreateInfo(vertexBufferSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible); 870 871 { 872 const Allocation& alloc = vertexBuffer.getAllocation(); 873 tcu::Vec4* const pVertices = reinterpret_cast<tcu::Vec4*>(alloc.getHostPtr()); 874 875 pVertices[0] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f); 876 pVertices[1] = tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f); 877 pVertices[2] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f); 878 879 pVertices[3] = tcu::Vec4(-1.0f, 1.0f, 0.5f, 1.0f); 880 pVertices[4] = tcu::Vec4( 1.0f, 1.0f, 1.0f, 1.0f); 881 pVertices[5] = tcu::Vec4( 1.0f, -1.0f, 0.5f, 1.0f); 882 883 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexBufferSizeBytes); 884 // No barrier needed, flushed memory is automatically visible 885 } 886 887 // Result buffer 888 889 const VkDeviceSize resultBufferSizeBytes = sizeof(deUint32); 890 const Buffer resultBuffer(vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); 891 892 { 893 const Allocation& alloc = resultBuffer.getAllocation(); 894 deUint32* const pData = static_cast<deUint32*>(alloc.getHostPtr()); 895 896 *pData = 0; 897 flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes); 898 } 899 900 // Render result buffer (to retrieve color attachment contents) 901 902 const VkDeviceSize colorBufferSizeBytes = tcu::getPixelSize(mapVkFormat(colorFormat)) * renderSize.x() * renderSize.y(); 903 const Buffer colorBuffer (vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible); 904 905 // Descriptors 906 907 const Unique<VkDescriptorSetLayout> descriptorSetLayout(DescriptorSetLayoutBuilder() 908 .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT) 909 .build(vk, device)); 910 911 const Unique<VkDescriptorPool> descriptorPool(DescriptorPoolBuilder() 912 .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) 913 .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); 914 915 const Unique<VkDescriptorSet> descriptorSet (makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); 916 const VkDescriptorBufferInfo resultBufferDescriptorInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes); 917 918 DescriptorSetUpdateBuilder() 919 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferDescriptorInfo) 920 .update(vk, device); 921 922 // Pipeline 923 924 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u)); 925 const Unique<VkShaderModule> fragmentModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0u)); 926 const Unique<VkRenderPass> renderPass (makeRenderPass(vk, device, colorFormat, m_useTestAttachment, testFormat)); 927 const Unique<VkFramebuffer> framebuffer (makeFramebuffer(vk, device, *renderPass, numUsedAttachmentImages, attachmentImages, renderSize)); 928 const Unique<VkPipelineLayout> pipelineLayout(makePipelineLayout(vk, device, *descriptorSetLayout)); 929 const Unique<VkPipeline> pipeline (makeGraphicsPipeline(vk, device, *pipelineLayout, *renderPass, *vertexModule, *fragmentModule, renderSize, 930 (m_testMode == MODE_DEPTH), (m_testMode == MODE_STENCIL))); 931 const Unique<VkCommandPool> cmdPool (makeCommandPool(vk, device, queueFamilyIndex)); 932 const Unique<VkCommandBuffer> cmdBuffer (makeCommandBuffer(vk, device, *cmdPool)); 933 934 // Draw commands 935 936 { 937 const VkRect2D renderArea = { 938 makeOffset2D(0, 0), 939 makeExtent2D(renderSize.x(), renderSize.y()), 940 }; 941 const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f); 942 const VkDeviceSize vertexBufferOffset = 0ull; 943 944 beginCommandBuffer(vk, *cmdBuffer); 945 946 { 947 const VkImageMemoryBarrier barriers[] = { 948 makeImageMemoryBarrier( 949 0u, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, 950 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, 951 *colorImage, colorSubresourceRange), 952 makeImageMemoryBarrier( 953 0u, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 954 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 955 *testImage, testSubresourceRange), 956 }; 957 958 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 959 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(barriers), barriers); 960 } 961 962 // Will clear the attachments with specified depth and stencil values. 963 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor, 0.5f, 0u); 964 965 vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); 966 vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); 967 vk.cmdBindVertexBuffers(*cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset); 968 969 // Mask half of the attachment image with value that will pass the stencil test. 970 if (m_useTestAttachment && m_testMode == MODE_STENCIL) 971 commandClearStencilAttachment(vk, *cmdBuffer, makeOffset2D(0, 0), makeExtent2D(renderSize.x()/2, renderSize.y()), 1u); 972 973 vk.cmdDraw(*cmdBuffer, numVertices, 1u, 0u, 0u); 974 endRenderPass(vk, *cmdBuffer); 975 976 { 977 const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( 978 VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes); 979 980 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 981 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL); 982 983 const VkImageMemoryBarrier preCopyColorImageBarrier = makeImageMemoryBarrier( 984 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, 985 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, 986 *colorImage, colorSubresourceRange); 987 988 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 989 0u, DE_NULL, 0u, DE_NULL, 1u, &preCopyColorImageBarrier); 990 991 const VkBufferImageCopy copyRegion = makeBufferImageCopy(VK_IMAGE_ASPECT_COLOR_BIT, renderSize); 992 vk.cmdCopyImageToBuffer(*cmdBuffer, *colorImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ©Region); 993 994 const VkBufferMemoryBarrier postCopyColorBufferBarrier = makeBufferMemoryBarrier( 995 VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes); 996 997 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 998 0u, DE_NULL, 1u, &postCopyColorBufferBarrier, 0u, DE_NULL); 999 } 1000 1001 endCommandBuffer(vk, *cmdBuffer); 1002 submitCommandsAndWait(vk, device, queue, *cmdBuffer); 1003 } 1004 1005 // Log result image 1006 { 1007 const Allocation& alloc = colorBuffer.getAllocation(); 1008 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), colorBufferSizeBytes); 1009 1010 const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, alloc.getHostPtr()); 1011 1012 tcu::TestLog& log = m_context.getTestContext().getLog(); 1013 log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess); 1014 } 1015 1016 // Verify results 1017 { 1018 const Allocation& alloc = resultBuffer.getAllocation(); 1019 invalidateMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes); 1020 1021 const int actualCounter = *static_cast<deInt32*>(alloc.getHostPtr()); 1022 const bool expectPartialResult = (m_useEarlyTests && m_useTestAttachment); 1023 const int expectedCounter = expectPartialResult ? renderSize.x() * renderSize.y() / 2 : renderSize.x() * renderSize.y(); 1024 const int tolerance = expectPartialResult ? de::max(renderSize.x(), renderSize.y()) * 3 : 0; 1025 const int expectedMin = de::max(0, expectedCounter - tolerance); 1026 const int expectedMax = expectedCounter + tolerance; 1027 1028 tcu::TestLog& log = m_context.getTestContext().getLog(); 1029 log << tcu::TestLog::Message << "Expected value" 1030 << (expectPartialResult ? " in range: [" + de::toString(expectedMin) + ", " + de::toString(expectedMax) + "]" : ": " + de::toString(expectedCounter)) 1031 << tcu::TestLog::EndMessage; 1032 log << tcu::TestLog::Message << "Result value: " << de::toString(actualCounter) << tcu::TestLog::EndMessage; 1033 1034 if (expectedMin <= actualCounter && actualCounter <= expectedMax) 1035 return tcu::TestStatus::pass("Success"); 1036 else 1037 return tcu::TestStatus::fail("Value out of range"); 1038 } 1039} 1040 1041TestInstance* EarlyFragmentTest::createInstance (Context& context) const 1042{ 1043 // Check required features 1044 { 1045 VkPhysicalDeviceFeatures features; 1046 context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &features); 1047 1048 // SSBO writes in fragment shader 1049 if (!features.fragmentStoresAndAtomics) 1050 throw tcu::NotSupportedError("Missing required feature: fragmentStoresAndAtomics"); 1051 } 1052 1053 return new EarlyFragmentTestInstance(context, m_flags); 1054} 1055 1056} // anonymous ns 1057 1058tcu::TestCaseGroup* createEarlyFragmentTests (tcu::TestContext& testCtx) 1059{ 1060 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "early_fragment", "early fragment test cases")); 1061 1062 static const struct 1063 { 1064 std::string caseName; 1065 deUint32 flags; 1066 } cases[] = 1067 { 1068 { "no_early_fragment_tests_depth", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS }, 1069 { "no_early_fragment_tests_stencil", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS }, 1070 { "early_fragment_tests_depth", FLAG_TEST_DEPTH }, 1071 { "early_fragment_tests_stencil", FLAG_TEST_STENCIL }, 1072 { "no_early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT }, 1073 { "no_early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_EARLY_FRAGMENT_TESTS | FLAG_DONT_USE_TEST_ATTACHMENT }, 1074 { "early_fragment_tests_depth_no_attachment", FLAG_TEST_DEPTH | FLAG_DONT_USE_TEST_ATTACHMENT }, 1075 { "early_fragment_tests_stencil_no_attachment", FLAG_TEST_STENCIL | FLAG_DONT_USE_TEST_ATTACHMENT }, 1076 }; 1077 1078 for (int i = 0; i < DE_LENGTH_OF_ARRAY(cases); ++i) 1079 testGroup->addChild(new EarlyFragmentTest(testCtx, cases[i].caseName, cases[i].flags)); 1080 1081 return testGroup.release(); 1082} 1083 1084} // pipeline 1085} // vkt 1086