1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Imagination Technologies Ltd. 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 Stencil Tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktPipelineStencilTests.hpp" 26 #include "vktPipelineClearUtil.hpp" 27 #include "vktPipelineImageUtil.hpp" 28 #include "vktPipelineVertexUtil.hpp" 29 #include "vktPipelineReferenceRenderer.hpp" 30 #include "vktPipelineUniqueRandomIterator.hpp" 31 #include "vktTestCase.hpp" 32 #include "vkImageUtil.hpp" 33 #include "vkMemUtil.hpp" 34 #include "vkPrograms.hpp" 35 #include "vkQueryUtil.hpp" 36 #include "vkRef.hpp" 37 #include "vkRefUtil.hpp" 38 #include "vkTypeUtil.hpp" 39 #include "tcuImageCompare.hpp" 40 #include "deMemory.h" 41 #include "deRandom.hpp" 42 #include "deStringUtil.hpp" 43 #include "deUniquePtr.hpp" 44 45 #include <algorithm> 46 #include <sstream> 47 #include <vector> 48 49 namespace vkt 50 { 51 namespace pipeline 52 { 53 54 using namespace vk; 55 56 namespace 57 { 58 59 bool isSupportedDepthStencilFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 60 { 61 VkFormatProperties formatProps; 62 63 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 64 65 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0; 66 } 67 68 class StencilOpStateUniqueRandomIterator : public UniqueRandomIterator<VkStencilOpState> 69 { 70 public: 71 StencilOpStateUniqueRandomIterator (int seed); 72 virtual ~StencilOpStateUniqueRandomIterator (void) {} 73 virtual VkStencilOpState getIndexedValue (deUint32 index); 74 75 private: 76 const static VkStencilOp m_stencilOps[]; 77 const static VkCompareOp m_compareOps[]; 78 79 // Pre-calculated constants 80 const static deUint32 m_stencilOpsLength; 81 const static deUint32 m_stencilOpsLength2; 82 const static deUint32 m_stencilOpsLength3; 83 const static deUint32 m_compareOpsLength; 84 85 // Total number of cross-combinations of (stencilFailOp x stencilPassOp x stencilDepthFailOp x stencilCompareOp) 86 const static deUint32 m_totalStencilOpStates; 87 }; 88 89 90 class StencilTest : public vkt::TestCase 91 { 92 public: 93 enum 94 { 95 QUAD_COUNT = 4 96 }; 97 98 struct StencilStateConfig 99 { 100 deUint32 frontReadMask; 101 deUint32 frontWriteMask; 102 deUint32 frontRef; 103 104 deUint32 backReadMask; 105 deUint32 backWriteMask; 106 deUint32 backRef; 107 }; 108 109 const static StencilStateConfig s_stencilStateConfigs[QUAD_COUNT]; 110 const static float s_quadDepths[QUAD_COUNT]; 111 112 113 StencilTest (tcu::TestContext& testContext, 114 const std::string& name, 115 const std::string& description, 116 VkFormat stencilFormat, 117 const VkStencilOpState& stencilOpStateFront, 118 const VkStencilOpState& stencilOpStateBack); 119 virtual ~StencilTest (void); 120 virtual void initPrograms (SourceCollections& sourceCollections) const; 121 virtual TestInstance* createInstance (Context& context) const; 122 123 private: 124 VkFormat m_stencilFormat; 125 const VkStencilOpState m_stencilOpStateFront; 126 const VkStencilOpState m_stencilOpStateBack; 127 }; 128 129 class StencilTestInstance : public vkt::TestInstance 130 { 131 public: 132 StencilTestInstance (Context& context, 133 VkFormat stencilFormat, 134 const VkStencilOpState& stencilOpStatesFront, 135 const VkStencilOpState& stencilOpStatesBack); 136 virtual ~StencilTestInstance (void); 137 virtual tcu::TestStatus iterate (void); 138 139 private: 140 tcu::TestStatus verifyImage (void); 141 142 VkStencilOpState m_stencilOpStateFront; 143 VkStencilOpState m_stencilOpStateBack; 144 const tcu::UVec2 m_renderSize; 145 const VkFormat m_colorFormat; 146 const VkFormat m_stencilFormat; 147 VkImageSubresourceRange m_stencilImageSubresourceRange; 148 149 VkImageCreateInfo m_colorImageCreateInfo; 150 Move<VkImage> m_colorImage; 151 de::MovePtr<Allocation> m_colorImageAlloc; 152 Move<VkImage> m_stencilImage; 153 de::MovePtr<Allocation> m_stencilImageAlloc; 154 Move<VkImageView> m_colorAttachmentView; 155 Move<VkImageView> m_stencilAttachmentView; 156 Move<VkRenderPass> m_renderPass; 157 Move<VkFramebuffer> m_framebuffer; 158 159 Move<VkShaderModule> m_vertexShaderModule; 160 Move<VkShaderModule> m_fragmentShaderModule; 161 162 Move<VkBuffer> m_vertexBuffer; 163 std::vector<Vertex4RGBA> m_vertices; 164 de::MovePtr<Allocation> m_vertexBufferAlloc; 165 166 Move<VkPipelineLayout> m_pipelineLayout; 167 Move<VkPipeline> m_graphicsPipelines[StencilTest::QUAD_COUNT]; 168 169 Move<VkCommandPool> m_cmdPool; 170 Move<VkCommandBuffer> m_cmdBuffer; 171 172 Move<VkFence> m_fence; 173 }; 174 175 176 // StencilOpStateUniqueRandomIterator 177 178 const VkStencilOp StencilOpStateUniqueRandomIterator::m_stencilOps[] = 179 { 180 VK_STENCIL_OP_KEEP, 181 VK_STENCIL_OP_ZERO, 182 VK_STENCIL_OP_REPLACE, 183 VK_STENCIL_OP_INCREMENT_AND_CLAMP, 184 VK_STENCIL_OP_DECREMENT_AND_CLAMP, 185 VK_STENCIL_OP_INVERT, 186 VK_STENCIL_OP_INCREMENT_AND_WRAP, 187 VK_STENCIL_OP_DECREMENT_AND_WRAP 188 }; 189 190 const VkCompareOp StencilOpStateUniqueRandomIterator::m_compareOps[] = 191 { 192 VK_COMPARE_OP_NEVER, 193 VK_COMPARE_OP_LESS, 194 VK_COMPARE_OP_EQUAL, 195 VK_COMPARE_OP_LESS_OR_EQUAL, 196 VK_COMPARE_OP_GREATER, 197 VK_COMPARE_OP_NOT_EQUAL, 198 VK_COMPARE_OP_GREATER_OR_EQUAL, 199 VK_COMPARE_OP_ALWAYS 200 }; 201 202 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength = DE_LENGTH_OF_ARRAY(m_stencilOps); 203 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength2 = m_stencilOpsLength * m_stencilOpsLength; 204 const deUint32 StencilOpStateUniqueRandomIterator::m_stencilOpsLength3 = m_stencilOpsLength2 * m_stencilOpsLength; 205 const deUint32 StencilOpStateUniqueRandomIterator::m_compareOpsLength = DE_LENGTH_OF_ARRAY(m_compareOps); 206 const deUint32 StencilOpStateUniqueRandomIterator::m_totalStencilOpStates = m_stencilOpsLength3 * m_compareOpsLength; 207 208 StencilOpStateUniqueRandomIterator::StencilOpStateUniqueRandomIterator (int seed) 209 : UniqueRandomIterator<VkStencilOpState>(m_totalStencilOpStates, m_totalStencilOpStates, seed) 210 { 211 } 212 213 VkStencilOpState StencilOpStateUniqueRandomIterator::getIndexedValue (deUint32 index) 214 { 215 const deUint32 stencilCompareOpIndex = index / m_stencilOpsLength3; 216 const deUint32 stencilCompareOpSeqIndex = stencilCompareOpIndex * m_stencilOpsLength3; 217 218 const deUint32 stencilDepthFailOpIndex = (index - stencilCompareOpSeqIndex) / m_stencilOpsLength2; 219 const deUint32 stencilDepthFailOpSeqIndex = stencilDepthFailOpIndex * m_stencilOpsLength2; 220 221 const deUint32 stencilPassOpIndex = (index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex) / m_stencilOpsLength; 222 const deUint32 stencilPassOpSeqIndex = stencilPassOpIndex * m_stencilOpsLength; 223 224 const deUint32 stencilFailOpIndex = index - stencilCompareOpSeqIndex - stencilDepthFailOpSeqIndex - stencilPassOpSeqIndex; 225 226 const VkStencilOpState stencilOpState = 227 { 228 m_stencilOps[stencilFailOpIndex], // VkStencilOp failOp; 229 m_stencilOps[stencilPassOpIndex], // VkStencilOp passOp; 230 m_stencilOps[stencilDepthFailOpIndex], // VkStencilOp depthFailOp; 231 m_compareOps[stencilCompareOpIndex], // VkCompareOp compareOp; 232 0x0, // deUint32 compareMask; 233 0x0, // deUint32 writeMask; 234 0x0 // deUint32 reference; 235 }; 236 237 return stencilOpState; 238 } 239 240 241 // StencilTest 242 243 const StencilTest::StencilStateConfig StencilTest::s_stencilStateConfigs[QUAD_COUNT] = 244 { 245 // frontReadMask frontWriteMask frontRef backReadMask backWriteMask backRef 246 { 0xFF, 0xFF, 0xAB, 0xF0, 0xFF, 0xFF }, 247 { 0xFF, 0xF0, 0xCD, 0xF0, 0xF0, 0xEF }, 248 { 0xF0, 0x0F, 0xEF, 0xFF, 0x0F, 0xCD }, 249 { 0xF0, 0x01, 0xFF, 0xFF, 0x01, 0xAB } 250 }; 251 252 const float StencilTest::s_quadDepths[QUAD_COUNT] = 253 { 254 0.1f, 255 0.0f, 256 0.3f, 257 0.2f 258 }; 259 260 StencilTest::StencilTest (tcu::TestContext& testContext, 261 const std::string& name, 262 const std::string& description, 263 VkFormat stencilFormat, 264 const VkStencilOpState& stencilOpStateFront, 265 const VkStencilOpState& stencilOpStateBack) 266 : vkt::TestCase (testContext, name, description) 267 , m_stencilFormat (stencilFormat) 268 , m_stencilOpStateFront (stencilOpStateFront) 269 , m_stencilOpStateBack (stencilOpStateBack) 270 { 271 } 272 273 StencilTest::~StencilTest (void) 274 { 275 } 276 277 TestInstance* StencilTest::createInstance (Context& context) const 278 { 279 return new StencilTestInstance(context, m_stencilFormat, m_stencilOpStateFront, m_stencilOpStateBack); 280 } 281 282 void StencilTest::initPrograms (SourceCollections& sourceCollections) const 283 { 284 sourceCollections.glslSources.add("color_vert") << glu::VertexSource( 285 "#version 310 es\n" 286 "layout(location = 0) in vec4 position;\n" 287 "layout(location = 1) in vec4 color;\n" 288 "layout(location = 0) out highp vec4 vtxColor;\n" 289 "void main (void)\n" 290 "{\n" 291 " gl_Position = position;\n" 292 " vtxColor = color;\n" 293 "}\n"); 294 295 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource( 296 "#version 310 es\n" 297 "layout(location = 0) in highp vec4 vtxColor;\n" 298 "layout(location = 0) out highp vec4 fragColor;\n" 299 "void main (void)\n" 300 "{\n" 301 " fragColor = vtxColor;\n" 302 "}\n"); 303 } 304 305 306 // StencilTestInstance 307 308 StencilTestInstance::StencilTestInstance (Context& context, 309 VkFormat stencilFormat, 310 const VkStencilOpState& stencilOpStateFront, 311 const VkStencilOpState& stencilOpStateBack) 312 : vkt::TestInstance (context) 313 , m_stencilOpStateFront (stencilOpStateFront) 314 , m_stencilOpStateBack (stencilOpStateBack) 315 , m_renderSize (32, 32) 316 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM) 317 , m_stencilFormat (stencilFormat) 318 { 319 const DeviceInterface& vk = context.getDeviceInterface(); 320 const VkDevice vkDevice = context.getDevice(); 321 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 322 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 323 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 324 325 // Create color image 326 { 327 const VkImageCreateInfo colorImageParams = 328 { 329 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 330 DE_NULL, // const void* pNext; 331 0u, // VkImageCreateFlags flags; 332 VK_IMAGE_TYPE_2D, // VkImageType imageType; 333 m_colorFormat, // VkFormat format; 334 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 335 1u, // deUint32 mipLevels; 336 1u, // deUint32 arrayLayers; 337 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 338 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 339 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 340 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 341 1u, // deUint32 queueFamilyIndexCount; 342 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 343 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 344 }; 345 346 m_colorImageCreateInfo = colorImageParams; 347 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo); 348 349 // Allocate and bind color image memory 350 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 351 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 352 } 353 354 // Create stencil image 355 { 356 // Check format support 357 if (!isSupportedDepthStencilFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_stencilFormat)) 358 throw tcu::NotSupportedError(std::string("Unsupported depth/stencil format: ") + getFormatName(m_stencilFormat)); 359 360 const VkImageCreateInfo stencilImageParams = 361 { 362 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 363 DE_NULL, // const void* pNext; 364 0u, // VkImageCreateFlags flags; 365 VK_IMAGE_TYPE_2D, // VkImageType imageType; 366 m_stencilFormat, // VkFormat format; 367 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 368 1u, // deUint32 mipLevels; 369 1u, // deUint32 arrayLayers; 370 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 371 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 372 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage; 373 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 374 1u, // deUint32 queueFamilyIndexCount; 375 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 376 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 377 }; 378 379 m_stencilImage = createImage(vk, vkDevice, &stencilImageParams); 380 381 // Allocate and bind stencil image memory 382 m_stencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_stencilImage), MemoryRequirement::Any); 383 VK_CHECK(vk.bindImageMemory(vkDevice, *m_stencilImage, m_stencilImageAlloc->getMemory(), m_stencilImageAlloc->getOffset())); 384 385 const VkImageAspectFlags aspect = (mapVkFormat(m_stencilFormat).order == tcu::TextureFormat::DS ? VK_IMAGE_ASPECT_STENCIL_BIT | VK_IMAGE_ASPECT_DEPTH_BIT 386 : VK_IMAGE_ASPECT_STENCIL_BIT); 387 m_stencilImageSubresourceRange = makeImageSubresourceRange(aspect, 0u, stencilImageParams.mipLevels, 0u, stencilImageParams.arrayLayers); 388 } 389 390 // Create color attachment view 391 { 392 const VkImageViewCreateInfo colorAttachmentViewParams = 393 { 394 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 395 DE_NULL, // const void* pNext; 396 0u, // VkImageViewCreateFlags flags; 397 *m_colorImage, // VkImage image; 398 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 399 m_colorFormat, // VkFormat format; 400 componentMappingRGBA, // VkComponentMapping components; 401 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 402 }; 403 404 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 405 } 406 407 // Create stencil attachment view 408 { 409 const VkImageViewCreateInfo stencilAttachmentViewParams = 410 { 411 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 412 DE_NULL, // const void* pNext; 413 0u, // VkImageViewCreateFlags flags; 414 *m_stencilImage, // VkImage image; 415 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 416 m_stencilFormat, // VkFormat format; 417 componentMappingRGBA, // VkComponentMapping components; 418 m_stencilImageSubresourceRange, // VkImageSubresourceRange subresourceRange; 419 }; 420 421 m_stencilAttachmentView = createImageView(vk, vkDevice, &stencilAttachmentViewParams); 422 } 423 424 // Create render pass 425 { 426 const VkAttachmentDescription colorAttachmentDescription = 427 { 428 0u, // VkAttachmentDescriptionFlags flags; 429 m_colorFormat, // VkFormat format; 430 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 431 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 432 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 433 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 434 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 435 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 436 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 437 }; 438 439 const VkAttachmentDescription stencilAttachmentDescription = 440 { 441 0u, // VkAttachmentDescriptionFlags flags; 442 m_stencilFormat, // VkFormat format; 443 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 444 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 445 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp; 446 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp; 447 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 448 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 449 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 450 }; 451 452 const VkAttachmentDescription attachments[2] = 453 { 454 colorAttachmentDescription, 455 stencilAttachmentDescription 456 }; 457 458 const VkAttachmentReference colorAttachmentReference = 459 { 460 0u, // deUint32 attachment; 461 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 462 }; 463 464 const VkAttachmentReference stencilAttachmentReference = 465 { 466 1u, // deUint32 attachment; 467 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout; 468 }; 469 470 const VkSubpassDescription subpassDescription = 471 { 472 0u, // VkSubpassDescriptionFlags flags; 473 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 474 0u, // deUint32 inputAttachmentCount; 475 DE_NULL, // const VkAttachmentReference* pInputAttachments; 476 1u, // deUint32 colorAttachmentCount; 477 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 478 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 479 &stencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 480 0u, // deUint32 preserveAttachmentCount; 481 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 482 }; 483 484 const VkRenderPassCreateInfo renderPassParams = 485 { 486 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 487 DE_NULL, // const void* pNext; 488 0u, // VkRenderPassCreateFlags flags; 489 2u, // deUint32 attachmentCount; 490 attachments, // const VkAttachmentDescription* pAttachments; 491 1u, // deUint32 subpassCount; 492 &subpassDescription, // const VkSubpassDescription* pSubpasses; 493 0u, // deUint32 dependencyCount; 494 DE_NULL // const VkSubpassDependency* pDependencies; 495 }; 496 497 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 498 } 499 500 // Create framebuffer 501 { 502 const VkImageView attachmentBindInfos[2] = { *m_colorAttachmentView, *m_stencilAttachmentView }; 503 504 const VkFramebufferCreateInfo framebufferParams = 505 { 506 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 507 DE_NULL, // const void* pNext; 508 0u, // VkFramebufferCreateFlags flags; 509 *m_renderPass, // VkRenderPass renderPass; 510 2u, // deUint32 attachmentCount; 511 attachmentBindInfos, // const VkImageView* pAttachments; 512 (deUint32)m_renderSize.x(), // deUint32 width; 513 (deUint32)m_renderSize.y(), // deUint32 height; 514 1u // deUint32 layers; 515 }; 516 517 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 518 } 519 520 // Create pipeline layout 521 { 522 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 523 { 524 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 525 DE_NULL, // const void* pNext; 526 0u, // VkPipelineLayoutCreateFlags flags; 527 0u, // deUint32 setLayoutCount; 528 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 529 0u, // deUint32 pushConstantRangeCount; 530 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 531 }; 532 533 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 534 } 535 536 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 537 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 538 539 // Create pipeline 540 { 541 const VkPipelineShaderStageCreateInfo shaderStages[2] = 542 { 543 { 544 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 545 DE_NULL, // const void* pNext; 546 0u, // VkPipelineShaderStageCreateFlags flags; 547 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 548 *m_vertexShaderModule, // VkShaderModule module; 549 "main", // const char* pName; 550 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 551 }, 552 { 553 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 554 DE_NULL, // const void* pNext; 555 0u, // VkPipelineShaderStageCreateFlags flags; 556 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 557 *m_fragmentShaderModule, // VkShaderModule module; 558 "main", // const char* pName; 559 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 560 } 561 }; 562 563 const VkVertexInputBindingDescription vertexInputBindingDescription = 564 { 565 0u, // deUint32 binding; 566 sizeof(Vertex4RGBA), // deUint32 strideInBytes; 567 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate; 568 }; 569 570 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 571 { 572 { 573 0u, // deUint32 location; 574 0u, // deUint32 binding; 575 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 576 0u // deUint32 offsetInBytes; 577 }, 578 { 579 1u, // deUint32 location; 580 0u, // deUint32 binding; 581 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 582 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offsetInBytes; 583 } 584 }; 585 586 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 587 { 588 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 589 DE_NULL, // const void* pNext; 590 0u, // VkPipelineVertexInputStateCreateFlags flags; 591 1u, // deUint32 vertexBindingDescriptionCount; 592 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 593 2u, // deUint32 vertexAttributeDescriptionCount; 594 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 595 }; 596 597 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 598 { 599 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 600 DE_NULL, // const void* pNext; 601 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 602 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 603 false // VkBool32 primitiveRestartEnable; 604 }; 605 606 const VkViewport viewport = 607 { 608 0.0f, // float x; 609 0.0f, // float y; 610 (float)m_renderSize.x(), // float width; 611 (float)m_renderSize.y(), // float height; 612 0.0f, // float minDepth; 613 1.0f // float maxDepth; 614 }; 615 616 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }; 617 618 const VkPipelineViewportStateCreateInfo viewportStateParams = 619 { 620 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 621 DE_NULL, // const void* pNext; 622 0u, // VkPipelineViewportStateCreateFlags flags; 623 1u, // deUint32 viewportCount; 624 &viewport, // const VkViewport* pViewports; 625 1u, // deUint32 scissorCount; 626 &scissor, // const VkRect2D* pScissors; 627 }; 628 629 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 630 { 631 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 632 DE_NULL, // const void* pNext; 633 0u, // VkPipelineRasterizationStateCreateFlags flags; 634 false, // VkBool32 depthClampEnable; 635 false, // VkBool32 rasterizerDiscardEnable; 636 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 637 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 638 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 639 false, // VkBool32 depthBiasEnable; 640 0.0f, // float depthBiasConstantFactor; 641 0.0f, // float depthBiasClamp; 642 0.0f, // float depthBiasSlopeFactor; 643 1.0f // float lineWidth; 644 }; 645 646 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = 647 { 648 false, // VkBool32 blendEnable; 649 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 650 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 651 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 652 VK_BLEND_FACTOR_ONE, // VKBLENDFACTOR SRCALPHABLENDFACTOR; 653 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 654 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 655 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 656 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 657 }; 658 659 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 660 { 661 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 662 DE_NULL, // const void* pNext; 663 0u, // VkPipelineColorBlendStateCreateFlags flags; 664 false, // VkBool32 logicOpEnable; 665 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 666 1u, // deUint32 attachmentCount; 667 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 668 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]; 669 }; 670 671 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 672 { 673 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 674 DE_NULL, // const void* pNext; 675 0u, // VkPipelineMultisampleStateCreateFlags flags; 676 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 677 false, // VkBool32 sampleShadingEnable; 678 0.0f, // float minSampleShading; 679 DE_NULL, // const VkSampleMask* pSampleMask; 680 false, // VkBool32 alphaToCoverageEnable; 681 false // VkBool32 alphaToOneEnable; 682 }; 683 684 const bool isDepthEnabled = (vk::mapVkFormat(m_stencilFormat).order != tcu::TextureFormat::S); 685 686 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 687 { 688 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 689 DE_NULL, // const void* pNext; 690 0u, // VkPipelineDepthStencilStateCreateFlags flags; 691 isDepthEnabled, // VkBool32 depthTestEnable; 692 isDepthEnabled, // VkBool32 depthWriteEnable; 693 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 694 false, // VkBool32 depthBoundsTestEnable; 695 true, // VkBool32 stencilTestEnable; 696 m_stencilOpStateFront, // VkStencilOpState front; 697 m_stencilOpStateBack, // VkStencilOpState back; 698 0.0f, // float minDepthBounds; 699 1.0f // float maxDepthBounds; 700 }; 701 702 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 703 { 704 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 705 DE_NULL, // const void* pNext; 706 0u, // VkPipelineCreateFlags flags; 707 2u, // deUint32 stageCount; 708 shaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 709 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 710 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 711 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 712 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 713 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 714 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 715 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 716 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 717 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 718 *m_pipelineLayout, // VkPipelineLayout layout; 719 *m_renderPass, // VkRenderPass renderPass; 720 0u, // deUint32 subpass; 721 0u, // VkPipeline basePipelineHandle; 722 0u // deInt32 basePipelineIndex; 723 }; 724 725 // Setup different stencil masks and refs in each quad 726 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++) 727 { 728 const StencilTest::StencilStateConfig& config = StencilTest::s_stencilStateConfigs[quadNdx]; 729 VkStencilOpState& front = depthStencilStateParams.front; 730 VkStencilOpState& back = depthStencilStateParams.back; 731 732 front.compareMask = config.frontReadMask; 733 front.writeMask = config.frontWriteMask; 734 front.reference = config.frontRef; 735 736 back.compareMask = config.backReadMask; 737 back.writeMask = config.backWriteMask; 738 back.reference = config.backRef; 739 740 m_graphicsPipelines[quadNdx] = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 741 } 742 } 743 744 745 // Create vertex buffer 746 { 747 const VkBufferCreateInfo vertexBufferParams = 748 { 749 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 750 DE_NULL, // const void* pNext; 751 0u, // VkBufferCreateFlags flags; 752 1024u, // VkDeviceSize size; 753 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 754 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 755 1u, // deUint32 queueFamilyIndexCount; 756 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 757 }; 758 759 m_vertices = createOverlappingQuads(); 760 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 761 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 762 763 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 764 765 // Adjust depths 766 for (int quadNdx = 0; quadNdx < 4; quadNdx++) 767 for (int vertexNdx = 0; vertexNdx < 6; vertexNdx++) 768 m_vertices[quadNdx * 6 + vertexNdx].position.z() = StencilTest::s_quadDepths[quadNdx]; 769 770 // Load vertices into vertex buffer 771 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA)); 772 773 const VkMappedMemoryRange flushRange = 774 { 775 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType; 776 DE_NULL, // const void* pNext; 777 m_vertexBufferAlloc->getMemory(), // VkDeviceMemory memory; 778 m_vertexBufferAlloc->getOffset(), // VkDeviceSize offset; 779 vertexBufferParams.size // VkDeviceSize size; 780 }; 781 782 vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange); 783 } 784 785 // Create command pool 786 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 787 788 // Create command buffer 789 { 790 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 791 { 792 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 793 DE_NULL, // const void* pNext; 794 0u, // VkCommandBufferUsageFlags flags; 795 (const VkCommandBufferInheritanceInfo*)DE_NULL, 796 }; 797 798 const VkClearValue attachmentClearValues[2] = 799 { 800 defaultClearValue(m_colorFormat), 801 defaultClearValue(m_stencilFormat) 802 }; 803 804 const VkRenderPassBeginInfo renderPassBeginInfo = 805 { 806 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 807 DE_NULL, // const void* pNext; 808 *m_renderPass, // VkRenderPass renderPass; 809 *m_framebuffer, // VkFramebuffer framebuffer; 810 { { 0, 0 } , { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 811 2, // deUint32 clearValueCount; 812 attachmentClearValues // const VkClearValue* pClearValues; 813 }; 814 815 const VkImageMemoryBarrier imageLayoutBarriers[] = 816 { 817 // color image layout transition 818 { 819 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 820 DE_NULL, // const void* pNext; 821 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 822 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 823 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 824 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 825 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 826 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 827 *m_colorImage, // VkImage image; 828 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 829 }, 830 // stencil image layout transition 831 { 832 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 833 DE_NULL, // const void* pNext; 834 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 835 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 836 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 837 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 838 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 839 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 840 *m_stencilImage, // VkImage image; 841 m_stencilImageSubresourceRange, // VkImageSubresourceRange subresourceRange; 842 }, 843 }; 844 845 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 846 847 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 848 849 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 850 0u, DE_NULL, 0u, DE_NULL, DE_LENGTH_OF_ARRAY(imageLayoutBarriers), imageLayoutBarriers); 851 852 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 853 854 const VkDeviceSize quadOffset = (m_vertices.size() / StencilTest::QUAD_COUNT) * sizeof(Vertex4RGBA); 855 856 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++) 857 { 858 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx; 859 860 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]); 861 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 862 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / StencilTest::QUAD_COUNT), 1, 0, 0); 863 } 864 865 vk.cmdEndRenderPass(*m_cmdBuffer); 866 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 867 } 868 869 // Create fence 870 m_fence = createFence(vk, vkDevice); 871 } 872 873 StencilTestInstance::~StencilTestInstance (void) 874 { 875 } 876 877 tcu::TestStatus StencilTestInstance::iterate (void) 878 { 879 const DeviceInterface& vk = m_context.getDeviceInterface(); 880 const VkDevice vkDevice = m_context.getDevice(); 881 const VkQueue queue = m_context.getUniversalQueue(); 882 const VkSubmitInfo submitInfo = 883 { 884 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 885 DE_NULL, // const void* pNext; 886 0u, // deUint32 waitSemaphoreCount; 887 DE_NULL, // const VkSemaphore* pWaitSemaphores; 888 (const VkPipelineStageFlags*)DE_NULL, 889 1u, // deUint32 commandBufferCount; 890 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 891 0u, // deUint32 signalSemaphoreCount; 892 DE_NULL // const VkSemaphore* pSignalSemaphores; 893 }; 894 895 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 896 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 897 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/)); 898 899 return verifyImage(); 900 } 901 902 tcu::TestStatus StencilTestInstance::verifyImage (void) 903 { 904 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 905 const tcu::TextureFormat tcuStencilFormat = mapVkFormat(m_stencilFormat); 906 const ColorVertexShader vertexShader; 907 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuStencilFormat); 908 const rr::Program program (&vertexShader, &fragmentShader); 909 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuStencilFormat, &program); 910 bool compareOk = false; 911 912 // Render reference image 913 { 914 // Set depth state 915 rr::RenderState renderState(refRenderer.getViewportState()); 916 917 renderState.fragOps.depthTestEnabled = true; 918 renderState.fragOps.depthFunc = mapVkCompareOp(VK_COMPARE_OP_LESS); 919 renderState.fragOps.stencilTestEnabled = true; 920 921 rr::StencilState& refStencilFront = renderState.fragOps.stencilStates[rr::FACETYPE_FRONT]; 922 rr::StencilState& refStencilBack = renderState.fragOps.stencilStates[rr::FACETYPE_BACK]; 923 924 refStencilFront.sFail = mapVkStencilOp(m_stencilOpStateFront.failOp); 925 refStencilFront.dpFail = mapVkStencilOp(m_stencilOpStateFront.depthFailOp); 926 refStencilFront.dpPass = mapVkStencilOp(m_stencilOpStateFront.passOp); 927 refStencilFront.func = mapVkCompareOp(m_stencilOpStateFront.compareOp); 928 929 refStencilBack.sFail = mapVkStencilOp(m_stencilOpStateBack.failOp); 930 refStencilBack.dpFail = mapVkStencilOp(m_stencilOpStateBack.depthFailOp); 931 refStencilBack.dpPass = mapVkStencilOp(m_stencilOpStateBack.passOp); 932 refStencilBack.func = mapVkCompareOp(m_stencilOpStateBack.compareOp); 933 934 // Reverse winding of vertices, as Vulkan screen coordinates start at upper left 935 std::vector<Vertex4RGBA> cwVertices(m_vertices); 936 for (size_t vertexNdx = 0; vertexNdx < cwVertices.size() - 2; vertexNdx += 3) 937 { 938 const Vertex4RGBA cwVertex1 = cwVertices[vertexNdx + 1]; 939 940 cwVertices[vertexNdx + 1] = cwVertices[vertexNdx + 2]; 941 cwVertices[vertexNdx + 2] = cwVertex1; 942 } 943 944 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++) 945 { 946 refStencilFront.ref = (int)StencilTest::s_stencilStateConfigs[quadNdx].frontRef; 947 refStencilFront.compMask = StencilTest::s_stencilStateConfigs[quadNdx].frontReadMask; 948 refStencilFront.writeMask = StencilTest::s_stencilStateConfigs[quadNdx].frontWriteMask; 949 950 refStencilBack.ref = (int)StencilTest::s_stencilStateConfigs[quadNdx].backRef; 951 refStencilBack.compMask = StencilTest::s_stencilStateConfigs[quadNdx].backReadMask; 952 refStencilBack.writeMask = StencilTest::s_stencilStateConfigs[quadNdx].backWriteMask; 953 954 refRenderer.draw(renderState, 955 rr::PRIMITIVETYPE_TRIANGLES, 956 std::vector<Vertex4RGBA>(cwVertices.begin() + quadNdx * 6, 957 cwVertices.begin() + (quadNdx + 1) * 6)); 958 } 959 } 960 961 // Compare result with reference image 962 { 963 const DeviceInterface& vk = m_context.getDeviceInterface(); 964 const VkDevice vkDevice = m_context.getDevice(); 965 const VkQueue queue = m_context.getUniversalQueue(); 966 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 967 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 968 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release()); 969 970 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(), 971 "IntImageCompare", 972 "Image comparison", 973 refRenderer.getAccess(), 974 result->getAccess(), 975 tcu::UVec4(2, 2, 2, 2), 976 tcu::IVec3(1, 1, 0), 977 true, 978 tcu::COMPARE_LOG_RESULT); 979 } 980 981 if (compareOk) 982 return tcu::TestStatus::pass("Result image matches reference"); 983 else 984 return tcu::TestStatus::fail("Image mismatch"); 985 } 986 987 988 // Utilities for test names 989 990 std::string getShortName (VkCompareOp compareOp) 991 { 992 const std::string fullName = getCompareOpName(compareOp); 993 994 DE_ASSERT(de::beginsWith(fullName, "VK_COMPARE_OP_")); 995 996 return de::toLower(fullName.substr(14)); 997 } 998 999 const char* getShortName (VkStencilOp stencilOp) 1000 { 1001 switch (stencilOp) 1002 { 1003 case VK_STENCIL_OP_KEEP: return "keep"; 1004 case VK_STENCIL_OP_ZERO: return "zero"; 1005 case VK_STENCIL_OP_REPLACE: return "repl"; 1006 case VK_STENCIL_OP_INCREMENT_AND_CLAMP: return "incc"; 1007 case VK_STENCIL_OP_DECREMENT_AND_CLAMP: return "decc"; 1008 case VK_STENCIL_OP_INVERT: return "inv"; 1009 case VK_STENCIL_OP_INCREMENT_AND_WRAP: return "wrap"; 1010 case VK_STENCIL_OP_DECREMENT_AND_WRAP: return "decw"; 1011 1012 default: 1013 DE_FATAL("Invalid VkStencilOpState value"); 1014 } 1015 return DE_NULL; 1016 } 1017 1018 std::string getStencilName(const VkStencilOpState& stencilOpState) 1019 { 1020 std::ostringstream name; 1021 1022 name << "fail_" << getShortName(stencilOpState.failOp) 1023 << "_pass_" << getShortName(stencilOpState.passOp) 1024 << "_dfail_" << getShortName(stencilOpState.depthFailOp) 1025 << "_comp_" << getShortName(stencilOpState.compareOp); 1026 1027 return name.str(); 1028 } 1029 1030 std::string getStencilStateSetName(const VkStencilOpState& stencilOpStateFront, 1031 const VkStencilOpState& stencilOpStateBack) 1032 { 1033 std::ostringstream name; 1034 1035 name << "front_" << getStencilName(stencilOpStateFront) 1036 << "_back_" << getStencilName(stencilOpStateBack); 1037 1038 return name.str(); 1039 } 1040 1041 std::string getStencilStateSetDescription(const VkStencilOpState& stencilOpStateFront, 1042 const VkStencilOpState& stencilOpStateBack) 1043 { 1044 std::ostringstream desc; 1045 1046 desc << "\nFront faces:\n" << stencilOpStateFront; 1047 desc << "Back faces:\n" << stencilOpStateBack; 1048 1049 return desc.str(); 1050 } 1051 1052 std::string getFormatCaseName (VkFormat format) 1053 { 1054 const std::string fullName = getFormatName(format); 1055 1056 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_")); 1057 1058 return de::toLower(fullName.substr(10)); 1059 } 1060 1061 } // anonymous 1062 1063 tcu::TestCaseGroup* createStencilTests (tcu::TestContext& testCtx) 1064 { 1065 const VkFormat stencilFormats[] = 1066 { 1067 VK_FORMAT_S8_UINT, 1068 VK_FORMAT_D16_UNORM_S8_UINT, 1069 VK_FORMAT_D24_UNORM_S8_UINT, 1070 VK_FORMAT_D32_SFLOAT_S8_UINT 1071 }; 1072 1073 de::MovePtr<tcu::TestCaseGroup> stencilTests (new tcu::TestCaseGroup(testCtx, "stencil", "Stencil tests")); 1074 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different stencil formats")); 1075 StencilOpStateUniqueRandomIterator stencilOpItr (123); 1076 1077 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(stencilFormats); formatNdx++) 1078 { 1079 const VkFormat stencilFormat = stencilFormats[formatNdx]; 1080 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx, 1081 getFormatCaseName(stencilFormat).c_str(), 1082 (std::string("Uses format ") + getFormatName(stencilFormat)).c_str())); 1083 1084 de::MovePtr<tcu::TestCaseGroup> stencilStateTests; 1085 { 1086 std::ostringstream desc; 1087 desc << "Draws 4 quads with the following depths and dynamic stencil states: "; 1088 for (int quadNdx = 0; quadNdx < StencilTest::QUAD_COUNT; quadNdx++) 1089 { 1090 const StencilTest::StencilStateConfig& stencilConfig = StencilTest::s_stencilStateConfigs[quadNdx]; 1091 1092 desc << "(" << quadNdx << ") " 1093 << "z = " << StencilTest::s_quadDepths[quadNdx] << ", " 1094 << "frontReadMask = " << stencilConfig.frontReadMask << ", " 1095 << "frontWriteMask = " << stencilConfig.frontWriteMask << ", " 1096 << "frontRef = " << stencilConfig.frontRef << ", " 1097 << "backReadMask = " << stencilConfig.backReadMask << ", " 1098 << "backWriteMask = " << stencilConfig.backWriteMask << ", " 1099 << "backRef = " << stencilConfig.backRef; 1100 } 1101 1102 stencilStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", desc.str().c_str())); 1103 } 1104 1105 stencilOpItr.reset(); 1106 1107 VkStencilOpState prevStencilState = stencilOpItr.next(); 1108 const VkStencilOpState firstStencilState = prevStencilState; 1109 1110 while (stencilOpItr.hasNext()) 1111 { 1112 const VkStencilOpState stencilState = stencilOpItr.next(); 1113 1114 // Use current stencil state in front fraces and previous state in back faces 1115 stencilStateTests->addChild(new StencilTest(testCtx, 1116 getStencilStateSetName(stencilState, prevStencilState), 1117 getStencilStateSetDescription(stencilState, prevStencilState), 1118 stencilFormat, 1119 stencilState, 1120 prevStencilState)); 1121 1122 prevStencilState = stencilState; 1123 } 1124 1125 // Use first stencil state with last stencil state. This would make the test suite cover all states in front and back faces. 1126 stencilStateTests->addChild(new StencilTest(testCtx, 1127 getStencilStateSetName(firstStencilState, prevStencilState), 1128 getStencilStateSetDescription(firstStencilState, prevStencilState), 1129 stencilFormat, 1130 firstStencilState, 1131 prevStencilState)); 1132 1133 formatTest->addChild(stencilStateTests.release()); 1134 formatTests->addChild(formatTest.release()); 1135 } 1136 stencilTests->addChild(formatTests.release()); 1137 1138 return stencilTests.release(); 1139 } 1140 1141 } // pipeline 1142 } // vkt 1143