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 Blend Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktPipelineBlendTests.hpp" 26#include "vktPipelineClearUtil.hpp" 27#include "vktPipelineImageUtil.hpp" 28#include "vktPipelineVertexUtil.hpp" 29#include "vktPipelineUniqueRandomIterator.hpp" 30#include "vktPipelineReferenceRenderer.hpp" 31#include "vktTestCase.hpp" 32#include "vkImageUtil.hpp" 33#include "vkMemUtil.hpp" 34#include "vkPlatform.hpp" 35#include "vkPrograms.hpp" 36#include "vkQueryUtil.hpp" 37#include "vkRef.hpp" 38#include "vkRefUtil.hpp" 39#include "tcuImageCompare.hpp" 40#include "tcuPlatform.hpp" 41#include "tcuTextureUtil.hpp" 42#include "deRandom.hpp" 43#include "deStringUtil.hpp" 44#include "deUniquePtr.hpp" 45#include <cstring> 46#include <set> 47#include <sstream> 48#include <vector> 49 50namespace vkt 51{ 52namespace pipeline 53{ 54 55using namespace vk; 56 57namespace 58{ 59 60bool isSupportedBlendFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format) 61{ 62 VkFormatProperties formatProps; 63 64 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 65 66 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) && 67 (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT); 68} 69 70class BlendStateUniqueRandomIterator : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState> 71{ 72public: 73 BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed); 74 virtual ~BlendStateUniqueRandomIterator (void) {} 75 VkPipelineColorBlendAttachmentState getIndexedValue (deUint32 index); 76 77private: 78 const static VkBlendFactor m_blendFactors[]; 79 const static VkBlendOp m_blendOps[]; 80 81 // Pre-calculated constants 82 const static deUint32 m_blendFactorsLength; 83 const static deUint32 m_blendFactorsLength2; 84 const static deUint32 m_blendFactorsLength3; 85 const static deUint32 m_blendFactorsLength4; 86 const static deUint32 m_blendOpsLength; 87 88 // Total number of cross-combinations of (srcBlendColor x destBlendColor x blendOpColor x srcBlendAlpha x destBlendAlpha x blendOpAlpha) 89 const static deUint32 m_totalBlendStates; 90}; 91 92class BlendTest : public vkt::TestCase 93{ 94public: 95 enum 96 { 97 QUAD_COUNT = 4 98 }; 99 100 const static VkColorComponentFlags s_colorWriteMasks[QUAD_COUNT]; 101 const static tcu::Vec4 s_blendConst; 102 103 BlendTest (tcu::TestContext& testContext, 104 const std::string& name, 105 const std::string& description, 106 const VkFormat colorFormat, 107 const VkPipelineColorBlendAttachmentState blendStates[QUAD_COUNT]); 108 virtual ~BlendTest (void); 109 virtual void initPrograms (SourceCollections& sourceCollections) const; 110 virtual TestInstance* createInstance (Context& context) const; 111 112private: 113 const VkFormat m_colorFormat; 114 VkPipelineColorBlendAttachmentState m_blendStates[QUAD_COUNT]; 115}; 116 117class BlendTestInstance : public vkt::TestInstance 118{ 119public: 120 BlendTestInstance (Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]); 121 virtual ~BlendTestInstance (void); 122 virtual tcu::TestStatus iterate (void); 123 124private: 125 static float getNormChannelThreshold (const tcu::TextureFormat& format, int numBits); 126 static tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format); 127 tcu::TestStatus verifyImage (void); 128 129 VkPipelineColorBlendAttachmentState m_blendStates[BlendTest::QUAD_COUNT]; 130 131 const tcu::UVec2 m_renderSize; 132 const VkFormat m_colorFormat; 133 134 VkImageCreateInfo m_colorImageCreateInfo; 135 Move<VkImage> m_colorImage; 136 de::MovePtr<Allocation> m_colorImageAlloc; 137 Move<VkImageView> m_colorAttachmentView; 138 Move<VkRenderPass> m_renderPass; 139 Move<VkFramebuffer> m_framebuffer; 140 141 Move<VkShaderModule> m_vertexShaderModule; 142 Move<VkShaderModule> m_fragmentShaderModule; 143 144 Move<VkBuffer> m_vertexBuffer; 145 std::vector<Vertex4RGBA> m_vertices; 146 de::MovePtr<Allocation> m_vertexBufferAlloc; 147 148 Move<VkPipelineLayout> m_pipelineLayout; 149 Move<VkPipeline> m_graphicsPipelines[BlendTest::QUAD_COUNT]; 150 151 Move<VkCommandPool> m_cmdPool; 152 Move<VkCommandBuffer> m_cmdBuffer; 153 154 Move<VkFence> m_fence; 155}; 156 157 158// BlendStateUniqueRandomIterator 159 160const VkBlendFactor BlendStateUniqueRandomIterator::m_blendFactors[] = 161{ 162 VK_BLEND_FACTOR_ZERO, 163 VK_BLEND_FACTOR_ONE, 164 VK_BLEND_FACTOR_SRC_COLOR, 165 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, 166 VK_BLEND_FACTOR_DST_COLOR, 167 VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, 168 VK_BLEND_FACTOR_SRC_ALPHA, 169 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, 170 VK_BLEND_FACTOR_DST_ALPHA, 171 VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, 172 VK_BLEND_FACTOR_CONSTANT_COLOR, 173 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, 174 VK_BLEND_FACTOR_CONSTANT_ALPHA, 175 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, 176 VK_BLEND_FACTOR_SRC_ALPHA_SATURATE 177}; 178 179const VkBlendOp BlendStateUniqueRandomIterator::m_blendOps[] = 180{ 181 VK_BLEND_OP_ADD, 182 VK_BLEND_OP_SUBTRACT, 183 VK_BLEND_OP_REVERSE_SUBTRACT, 184 VK_BLEND_OP_MIN, 185 VK_BLEND_OP_MAX 186}; 187 188const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength = DE_LENGTH_OF_ARRAY(m_blendFactors); 189const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength2 = m_blendFactorsLength * m_blendFactorsLength; 190const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength3 = m_blendFactorsLength2 * m_blendFactorsLength; 191const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength4 = m_blendFactorsLength3 * m_blendFactorsLength; 192const deUint32 BlendStateUniqueRandomIterator::m_blendOpsLength = DE_LENGTH_OF_ARRAY(m_blendOps); 193const deUint32 BlendStateUniqueRandomIterator::m_totalBlendStates = m_blendFactorsLength4 * m_blendOpsLength * m_blendOpsLength; 194 195 196BlendStateUniqueRandomIterator::BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed) 197 : UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed) 198{ 199} 200 201VkPipelineColorBlendAttachmentState BlendStateUniqueRandomIterator::getIndexedValue (deUint32 index) 202{ 203 const deUint32 blendOpAlphaIndex = index / (m_blendFactorsLength4 * m_blendOpsLength); 204 const deUint32 blendOpAlphaSeqIndex = blendOpAlphaIndex * (m_blendFactorsLength4 * m_blendOpsLength); 205 206 const deUint32 destBlendAlphaIndex = (index - blendOpAlphaSeqIndex) / (m_blendFactorsLength3 * m_blendOpsLength); 207 const deUint32 destBlendAlphaSeqIndex = destBlendAlphaIndex * (m_blendFactorsLength3 * m_blendOpsLength); 208 209 const deUint32 srcBlendAlphaIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex) / (m_blendFactorsLength2 * m_blendOpsLength); 210 const deUint32 srcBlendAlphaSeqIndex = srcBlendAlphaIndex * (m_blendFactorsLength2 * m_blendOpsLength); 211 212 const deUint32 blendOpColorIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex) / m_blendFactorsLength2; 213 const deUint32 blendOpColorSeqIndex = blendOpColorIndex * m_blendFactorsLength2; 214 215 const deUint32 destBlendColorIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex) / m_blendFactorsLength; 216 const deUint32 destBlendColorSeqIndex = destBlendColorIndex * m_blendFactorsLength; 217 218 const deUint32 srcBlendColorIndex = index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex - destBlendColorSeqIndex; 219 220 const VkPipelineColorBlendAttachmentState blendAttachmentState = 221 { 222 true, // VkBool32 blendEnable; 223 m_blendFactors[srcBlendColorIndex], // VkBlendFactor srcColorBlendFactor; 224 m_blendFactors[destBlendColorIndex], // VkBlendFactor dstColorBlendFactor; 225 m_blendOps[blendOpColorIndex], // VkBlendOp colorBlendOp; 226 m_blendFactors[srcBlendAlphaIndex], // VkBlendFactor srcAlphaBlendFactor; 227 m_blendFactors[destBlendAlphaIndex], // VkBlendFactor dstAlphaBlendFactor; 228 m_blendOps[blendOpAlphaIndex], // VkBlendOp alphaBlendOp; 229 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask; 230 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT 231 }; 232 233 return blendAttachmentState; 234} 235 236 237// BlendTest 238 239const VkColorComponentFlags BlendTest::s_colorWriteMasks[BlendTest::QUAD_COUNT] = { VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT, // Pair of channels: R & G 240 VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT, // Pair of channels: G & B 241 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, // Pair of channels: B & A 242 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT }; // All channels 243 244const tcu::Vec4 BlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f); 245 246BlendTest::BlendTest (tcu::TestContext& testContext, 247 const std::string& name, 248 const std::string& description, 249 const VkFormat colorFormat, 250 const VkPipelineColorBlendAttachmentState blendStates[QUAD_COUNT]) 251 : vkt::TestCase (testContext, name, description) 252 , m_colorFormat(colorFormat) 253{ 254 deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * QUAD_COUNT); 255} 256 257BlendTest::~BlendTest (void) 258{ 259} 260 261TestInstance* BlendTest::createInstance(Context& context) const 262{ 263 return new BlendTestInstance(context, m_colorFormat, m_blendStates); 264} 265 266void BlendTest::initPrograms (SourceCollections& sourceCollections) const 267{ 268 std::ostringstream fragmentSource; 269 270 sourceCollections.glslSources.add("color_vert") << glu::VertexSource( 271 "#version 310 es\n" 272 "layout(location = 0) in highp vec4 position;\n" 273 "layout(location = 1) in highp vec4 color;\n" 274 "layout(location = 0) out highp vec4 vtxColor;\n" 275 "void main (void)\n" 276 "{\n" 277 " gl_Position = position;\n" 278 " vtxColor = color;\n" 279 "}\n"); 280 281 fragmentSource << "#version 310 es\n" 282 "layout(location = 0) in highp vec4 vtxColor;\n" 283 "layout(location = 0) out highp vec4 fragColor;\n" 284 "void main (void)\n" 285 "{\n" 286 " fragColor = vtxColor;\n" 287 "}\n"; 288 289 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str()); 290} 291 292 293// BlendTestInstance 294 295BlendTestInstance::BlendTestInstance (Context& context, 296 const VkFormat colorFormat, 297 const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]) 298 : vkt::TestInstance (context) 299 , m_renderSize (32, 32) 300 , m_colorFormat (colorFormat) 301{ 302 const DeviceInterface& vk = m_context.getDeviceInterface(); 303 const VkDevice vkDevice = m_context.getDevice(); 304 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 305 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 306 307 // Copy depth operators 308 deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * BlendTest::QUAD_COUNT); 309 310 // Create color image 311 { 312 if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_colorFormat)) 313 throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_colorFormat)); 314 315 const VkImageCreateInfo colorImageParams = 316 { 317 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 318 DE_NULL, // const void* pNext; 319 0u, // VkImageCreateFlags flags; 320 VK_IMAGE_TYPE_2D, // VkImageType imageType; 321 m_colorFormat, // VkFormat format; 322 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 323 1u, // deUint32 mipLevels; 324 1u, // deUint32 arrayLayers; 325 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 326 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 327 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 328 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 329 1u, // deUint32 queueFamilyIndexCount; 330 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 331 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 332 }; 333 334 m_colorImageCreateInfo = colorImageParams; 335 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo); 336 337 // Allocate and bind color image memory 338 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any); 339 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); 340 } 341 342 // Create color attachment view 343 { 344 const VkImageViewCreateInfo colorAttachmentViewParams = 345 { 346 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 347 DE_NULL, // const void* pNext; 348 0u, // VkImageViewCreateFlags flags; 349 *m_colorImage, // VkImage image; 350 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 351 m_colorFormat, // VkFormat format; 352 {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY}, 353 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 354 }; 355 356 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 357 } 358 359 // Create render pass 360 { 361 const VkAttachmentDescription colorAttachmentDescription = 362 { 363 0u, // VkAttachmentDescriptionFlags flags; 364 m_colorFormat, // VkFormat format; 365 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 366 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 367 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 368 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 369 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 370 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 371 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout; 372 }; 373 374 const VkAttachmentReference colorAttachmentReference = 375 { 376 0u, // deUint32 attachment; 377 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 378 }; 379 380 const VkSubpassDescription subpassDescription = 381 { 382 0u, // VkSubpassDescriptionFlag flags; 383 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 384 0u, // deUint32 inputAttachmentCount; 385 DE_NULL, // const VkAttachmentReference* pInputAttachments; 386 1u, // deUint32 colorAttachmentCount; 387 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 388 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 389 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; 390 0u, // deUint32 preserveAttachmentCount; 391 DE_NULL // const VkAttachmentReference* pPreserveAttachments; 392 }; 393 394 const VkRenderPassCreateInfo renderPassParams = 395 { 396 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 397 DE_NULL, // const void* pNext; 398 0u, // VkRenderPassCreateFlags flags; 399 1u, // deUint32 attachmentCount; 400 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 401 1u, // deUint32 subpassCount; 402 &subpassDescription, // const VkSubpassDescription* pSubpasses; 403 0u, // deUint32 dependencyCount; 404 DE_NULL // const VkSubpassDependency* pDependencies; 405 }; 406 407 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams); 408 } 409 410 // Create framebuffer 411 { 412 const VkFramebufferCreateInfo framebufferParams = 413 { 414 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 415 DE_NULL, // const void* pNext; 416 0u, // VkFramebufferCreateFlags flags; 417 *m_renderPass, // VkRenderPass renderPass; 418 1u, // deUint32 attachmentCount; 419 &m_colorAttachmentView.get(), // const VkImageView* pAttachments; 420 (deUint32)m_renderSize.x(), // deUint32 width; 421 (deUint32)m_renderSize.y(), // deUint32 height; 422 1u // deUint32 layers; 423 }; 424 425 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 426 } 427 428 // Create pipeline layout 429 { 430 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 431 { 432 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 433 DE_NULL, // const void* pNext; 434 0u, // VkPipelineLayoutCreateFlags flags; 435 0u, // deUint32 setLayoutCount; 436 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 437 0u, // deUint32 pushConstantRangeCount; 438 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 439 }; 440 441 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 442 } 443 444 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 445 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 446 447 // Create pipeline 448 { 449 const VkPipelineShaderStageCreateInfo shaderStages[2] = 450 { 451 { 452 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 453 DE_NULL, // const void* pNext; 454 0u, // VkPipelineShaderStageCreateFlags flags; 455 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage; 456 *m_vertexShaderModule, // VkShaderModule module; 457 "main", // const char* pName; 458 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 459 }, 460 { 461 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 462 DE_NULL, // const void* pNext; 463 0u, // VkPipelineShaderStageCreateFlags flags; 464 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage; 465 *m_fragmentShaderModule, // VkShaderModule module; 466 "main", // const char* pName; 467 DE_NULL // const VkSpecializationInfo* pSpecializationInfo; 468 } 469 }; 470 471 const VkVertexInputBindingDescription vertexInputBindingDescription = 472 { 473 0u, // deUint32 binding; 474 sizeof(Vertex4RGBA), // deUint32 strideInBytes; 475 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate; 476 }; 477 478 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = 479 { 480 { 481 0u, // deUint32 location; 482 0u, // deUint32 binding; 483 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 484 0u // deUint32 offset; 485 }, 486 { 487 1u, // deUint32 location; 488 0u, // deUint32 binding; 489 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 490 (deUint32)(sizeof(float) * 4), // deUint32 offset; 491 } 492 }; 493 494 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = 495 { 496 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 497 DE_NULL, // const void* pNext; 498 0u, // VkPipelineVertexInputStateCreateFlags flags; 499 1u, // deUint32 vertexBindingDescriptionCount; 500 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 501 2u, // deUint32 vertexAttributeDescriptionCount; 502 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 503 }; 504 505 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams = 506 { 507 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 508 DE_NULL, // const void* pNext; 509 0u, // VkPipelineInputAssemblyStateCreateFlags flags; 510 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology; 511 false // VkBool32 primitiveRestartEnable; 512 }; 513 514 const VkViewport viewport = 515 { 516 0.0f, // float x; 517 0.0f, // float y; 518 (float)m_renderSize.x(), // float width; 519 (float)m_renderSize.y(), // float height; 520 0.0f, // float minDepth; 521 1.0f // float maxDepth; 522 }; 523 524 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }; 525 526 const VkPipelineViewportStateCreateInfo viewportStateParams = 527 { 528 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 529 DE_NULL, // const void* pNext; 530 0u, // VkPipelineViewportStateCreateFlags flags; 531 1u, // deUint32 viewportCount; 532 &viewport, // const VkViewport* pViewports; 533 1u, // deUint32 scissorCount; 534 &scissor // const VkRect2D* pScissors; 535 }; 536 537 const VkPipelineRasterizationStateCreateInfo rasterStateParams = 538 { 539 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 540 DE_NULL, // const void* pNext; 541 0u, // VkPipelineRasterizationStateCreateFlags flags; 542 false, // VkBool32 depthClampEnable; 543 false, // VkBool32 rasterizerDiscardEnable; 544 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 545 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 546 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 547 false, // VkBool32 depthBiasEnable; 548 0.0f, // float depthBiasConstantFactor; 549 0.0f, // float depthBiasClamp; 550 0.0f, // float depthBiasSlopeFactor; 551 1.0f // float lineWidth; 552 }; 553 554 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = 555 { 556 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 557 DE_NULL, // const void* pNext; 558 0u, // VkPipelineMultisampleStateCreateFlags flags; 559 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 560 false, // VkBool32 sampleShadingEnable; 561 0.0f, // float minSampleShading; 562 DE_NULL, // const VkSampleMask* pSampleMask; 563 false, // VkBool32 alphaToCoverageEnable; 564 false // VkBool32 alphaToOneEnable; 565 }; 566 567 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = 568 { 569 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 570 DE_NULL, // const void* pNext; 571 0u, // VkPipelineDepthStencilStateCreateFlags flags; 572 false, // VkBool32 depthTestEnable; 573 false, // VkBool32 depthWriteEnable; 574 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 575 false, // VkBool32 depthBoundsTestEnable; 576 false, // VkBool32 stencilTestEnable; 577 // VkStencilOpState front; 578 { 579 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 580 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 581 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 582 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 583 0u, // deUint32 compareMask; 584 0u, // deUint32 writeMask; 585 0u // deUint32 reference; 586 }, 587 // VkStencilOpState back; 588 { 589 VK_STENCIL_OP_KEEP, // VkStencilOp failOp; 590 VK_STENCIL_OP_KEEP, // VkStencilOp passOp; 591 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp; 592 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp; 593 0u, // deUint32 compareMask; 594 0u, // deUint32 writeMask; 595 0u // deUint32 reference; 596 }, 597 0.0f, // float minDepthBounds; 598 1.0f // float maxDepthBounds; 599 }; 600 601 // The color blend attachment will be set up before creating the graphics pipeline. 602 VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 603 { 604 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 605 DE_NULL, // const void* pNext; 606 0u, // VkPipelineColorBlendStateCreateFlags flags; 607 false, // VkBool32 logicOpEnable; 608 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 609 0u, // deUint32 attachmentCount; 610 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments; 611 { // float blendConstants[4]; 612 BlendTest::s_blendConst.x(), 613 BlendTest::s_blendConst.y(), 614 BlendTest::s_blendConst.z(), 615 BlendTest::s_blendConst.w() 616 } 617 }; 618 619 const VkGraphicsPipelineCreateInfo graphicsPipelineParams = 620 { 621 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 622 DE_NULL, // const void* pNext; 623 0u, // VkPipelineCreateFlags flags; 624 2u, // deUint32 stageCount; 625 shaderStages, // const VkPipelineShaderStageCreateInfo* pStages; 626 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 627 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 628 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState; 629 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState; 630 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 631 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 632 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 633 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 634 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 635 *m_pipelineLayout, // VkPipelineLayout layout; 636 *m_renderPass, // VkRenderPass renderPass; 637 0u, // deUint32 subpass; 638 0u, // VkPipeline basePipelineHandle; 639 0u // deInt32 basePipelineIndex; 640 }; 641 642 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 643 { 644 colorBlendStateParams.attachmentCount = 1u; 645 colorBlendStateParams.pAttachments = &m_blendStates[quadNdx]; 646 m_graphicsPipelines[quadNdx] = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams); 647 } 648 } 649 650 // Create vertex buffer 651 { 652 const VkBufferCreateInfo vertexBufferParams = 653 { 654 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 655 DE_NULL, // const void* pNext; 656 0u, // VkBufferCreateFlags flags; 657 1024u, // VkDeviceSize size; 658 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage; 659 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 660 1u, // deUint32 queueFamilyIndexCount; 661 &queueFamilyIndex // const deUint32* pQueueFamilyIndices; 662 }; 663 664 m_vertices = createOverlappingQuads(); 665 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams); 666 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible); 667 668 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); 669 670 // Adjust vertex colors 671 if (!isFloatFormat(m_colorFormat)) 672 { 673 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(mapVkFormat(m_colorFormat)); 674 for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++) 675 m_vertices[vertexNdx].color = (m_vertices[vertexNdx].color - formatInfo.lookupBias) / formatInfo.lookupScale; 676 } 677 678 // Upload vertex data 679 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA)); 680 681 const VkMappedMemoryRange flushRange = 682 { 683 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType; 684 DE_NULL, // const void* pNext; 685 m_vertexBufferAlloc->getMemory(), // VkDeviceMemory memory; 686 m_vertexBufferAlloc->getOffset(), // VkDeviceSize offset; 687 vertexBufferParams.size // VkDeviceSize size; 688 }; 689 690 vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange); 691 } 692 693 // Create command pool 694 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 695 696 // Create command buffer 697 { 698 const VkCommandBufferBeginInfo cmdBufferBeginInfo = 699 { 700 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 701 DE_NULL, // const void* pNext; 702 0u, // VkCommandBufferUsageFlags flags; 703 (const VkCommandBufferInheritanceInfo*)DE_NULL, 704 }; 705 706 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat); 707 708 const VkRenderPassBeginInfo renderPassBeginInfo = 709 { 710 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 711 DE_NULL, // const void* pNext; 712 *m_renderPass, // VkRenderPass renderPass; 713 *m_framebuffer, // VkFramebuffer framebuffer; 714 { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea; 715 1, // deUint32 clearValueCount; 716 &attachmentClearValue // const VkClearValue* pClearValues; 717 }; 718 719 // Color image layout transition 720 const VkImageMemoryBarrier imageLayoutBarrier = 721 { 722 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 723 DE_NULL, // const void* pNext; 724 (VkAccessFlags)0, // VkAccessFlags srcAccessMask; 725 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 726 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 727 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 728 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex; 729 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex; 730 *m_colorImage, // VkImage image; 731 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 732 }; 733 734 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 735 736 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo)); 737 738 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0, 739 0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier); 740 741 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 742 743 const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA); 744 745 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 746 { 747 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx; 748 749 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]); 750 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset); 751 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / BlendTest::QUAD_COUNT), 1, 0, 0); 752 } 753 754 vk.cmdEndRenderPass(*m_cmdBuffer); 755 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer)); 756 } 757 758 // Create fence 759 m_fence = createFence(vk, vkDevice); 760} 761 762BlendTestInstance::~BlendTestInstance (void) 763{ 764} 765 766tcu::TestStatus BlendTestInstance::iterate (void) 767{ 768 const DeviceInterface& vk = m_context.getDeviceInterface(); 769 const VkDevice vkDevice = m_context.getDevice(); 770 const VkQueue queue = m_context.getUniversalQueue(); 771 const VkSubmitInfo submitInfo = 772 { 773 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 774 DE_NULL, // const void* pNext; 775 0u, // deUint32 waitSemaphoreCount; 776 DE_NULL, // const VkSemaphore* pWaitSemaphores; 777 (const VkPipelineStageFlags*)DE_NULL, 778 1u, // deUint32 commandBufferCount; 779 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers; 780 0u, // deUint32 signalSemaphoreCount; 781 DE_NULL // const VkSemaphore* pSignalSemaphores; 782 }; 783 784 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get())); 785 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence)); 786 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */)); 787 788 return verifyImage(); 789} 790 791float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits) 792{ 793 switch (tcu::getTextureChannelClass(format.type)) 794 { 795 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: return BlendTest::QUAD_COUNT / static_cast<float>((1 << numBits) - 1); 796 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: return BlendTest::QUAD_COUNT / static_cast<float>((1 << (numBits - 1)) - 1); 797 default: 798 break; 799 } 800 801 DE_ASSERT(false); 802 return 0.0f; 803} 804 805tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format) 806{ 807 using tcu::Vec4; 808 using tcu::TextureFormat; 809 810 Vec4 threshold(0.01f); 811 812 switch (format.type) 813 { 814 case TextureFormat::UNORM_BYTE_44: 815 threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f); 816 break; 817 818 case TextureFormat::UNORM_SHORT_565: 819 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f); 820 break; 821 822 case TextureFormat::UNORM_SHORT_555: 823 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f); 824 break; 825 826 case TextureFormat::UNORM_SHORT_4444: 827 threshold = Vec4(getNormChannelThreshold(format, 4)); 828 break; 829 830 case TextureFormat::UNORM_SHORT_5551: 831 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f); 832 break; 833 834 case TextureFormat::UNORM_INT_1010102_REV: 835 case TextureFormat::SNORM_INT_1010102_REV: 836 threshold = Vec4(getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), 0.34f); 837 break; 838 839 case TextureFormat::UNORM_INT8: 840 case TextureFormat::SNORM_INT8: 841 threshold = Vec4(getNormChannelThreshold(format, 8)); 842 break; 843 844 case TextureFormat::UNORM_INT16: 845 case TextureFormat::SNORM_INT16: 846 threshold = Vec4(getNormChannelThreshold(format, 16)); 847 break; 848 849 case TextureFormat::UNORM_INT32: 850 case TextureFormat::SNORM_INT32: 851 threshold = Vec4(getNormChannelThreshold(format, 32)); 852 break; 853 854 case TextureFormat::HALF_FLOAT: 855 threshold = Vec4(0.005f); 856 break; 857 858 case TextureFormat::FLOAT: 859 threshold = Vec4(0.00001f); 860 break; 861 862 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV: 863 threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f); 864 break; 865 866 case TextureFormat::UNSIGNED_INT_999_E5_REV: 867 threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f); 868 break; 869 870 default: 871 DE_ASSERT(false); 872 } 873 874 // Return value matching the channel order specified by the format 875 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA) 876 return threshold.swizzle(2, 1, 0, 3); 877 else 878 return threshold; 879} 880 881tcu::TestStatus BlendTestInstance::verifyImage (void) 882{ 883 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat); 884 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); // Undefined depth/stencil format 885 const ColorVertexShader vertexShader; 886 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat); 887 const rr::Program program (&vertexShader, &fragmentShader); 888 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program); 889 bool compareOk = false; 890 891 // Render reference image 892 { 893 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 894 { 895 const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx]; 896 897 // Set blend state 898 rr::RenderState renderState (refRenderer.getViewportState()); 899 renderState.fragOps.blendMode = rr::BLENDMODE_STANDARD; 900 renderState.fragOps.blendRGBState.srcFunc = mapVkBlendFactor(blendState.srcColorBlendFactor); 901 renderState.fragOps.blendRGBState.dstFunc = mapVkBlendFactor(blendState.dstColorBlendFactor); 902 renderState.fragOps.blendRGBState.equation = mapVkBlendOp(blendState.colorBlendOp); 903 renderState.fragOps.blendAState.srcFunc = mapVkBlendFactor(blendState.srcAlphaBlendFactor); 904 renderState.fragOps.blendAState.dstFunc = mapVkBlendFactor(blendState.dstAlphaBlendFactor); 905 renderState.fragOps.blendAState.equation = mapVkBlendOp(blendState.alphaBlendOp); 906 renderState.fragOps.blendColor = BlendTest::s_blendConst; 907 renderState.fragOps.colorMask = mapVkColorComponentFlags(BlendTest::s_colorWriteMasks[quadNdx]); 908 909 refRenderer.draw(renderState, 910 rr::PRIMITIVETYPE_TRIANGLES, 911 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6, 912 m_vertices.begin() + (quadNdx + 1) * 6)); 913 } 914 } 915 916 917 // Compare result with reference image 918 { 919 const DeviceInterface& vk = m_context.getDeviceInterface(); 920 const VkDevice vkDevice = m_context.getDevice(); 921 const VkQueue queue = m_context.getUniversalQueue(); 922 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 923 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice())); 924 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release()); 925 const tcu::Vec4 threshold (getFormatThreshold(tcuColorFormat)); 926 927 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(), 928 "FloatImageCompare", 929 "Image comparison", 930 refRenderer.getAccess(), 931 result->getAccess(), 932 threshold, 933 tcu::COMPARE_LOG_RESULT); 934 } 935 936 if (compareOk) 937 return tcu::TestStatus::pass("Result image matches reference"); 938 else 939 return tcu::TestStatus::fail("Image mismatch"); 940} 941 942} // anonymous 943 944std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState) 945{ 946 const char* shortBlendFactorNames[] = 947 { 948 "z", // VK_BLEND_ZERO 949 "o", // VK_BLEND_ONE 950 "sc", // VK_BLEND_SRC_COLOR 951 "1msc", // VK_BLEND_ONE_MINUS_SRC_COLOR 952 "dc", // VK_BLEND_DEST_COLOR 953 "1mdc", // VK_BLEND_ONE_MINUS_DEST_COLOR 954 "sa", // VK_BLEND_SRC_ALPHA 955 "1msa", // VK_BLEND_ONE_MINUS_SRC_ALPHA 956 "da", // VK_BLEND_DEST_ALPHA 957 "1mda", // VK_BLEND_ONE_MINUS_DEST_ALPHA 958 "cc", // VK_BLEND_CONSTANT_COLOR 959 "1mcc", // VK_BLEND_ONE_MINUS_CONSTANT_COLOR 960 "ca", // VK_BLEND_CONSTANT_ALPHA 961 "1mca", // VK_BLEND_ONE_MINUS_CONSTANT_ALPHA 962 "sas" // VK_BLEND_SRC_ALPHA_SATURATE 963 }; 964 965 const char* blendOpNames[] = 966 { 967 "add", // VK_BLEND_OP_ADD 968 "sub", // VK_BLEND_OP_SUBTRACT 969 "rsub", // VK_BLEND_OP_REVERSE_SUBTRACT 970 "min", // VK_BLEND_OP_MIN 971 "max", // VK_BLEND_OP_MAX 972 }; 973 974 std::ostringstream shortName; 975 976 shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp]; 977 shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp]; 978 979 return shortName.str(); 980} 981 982std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]) 983{ 984 std::ostringstream name; 985 986 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 987 { 988 name << getBlendStateName(blendStates[quadNdx]); 989 990 if (quadNdx < BlendTest::QUAD_COUNT - 1) 991 name << "-"; 992 } 993 994 return name.str(); 995} 996 997std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]) 998{ 999 std::ostringstream description; 1000 1001 description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n"; 1002 1003 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 1004 description << blendStates[quadNdx] << "\n"; 1005 1006 return description.str(); 1007} 1008 1009std::string getFormatCaseName (VkFormat format) 1010{ 1011 const std::string fullName = getFormatName(format); 1012 1013 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_")); 1014 1015 return de::toLower(fullName.substr(10)); 1016} 1017 1018tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx) 1019{ 1020 const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT; 1021 1022 // Formats that are dEQP-compatible, non-integer and uncompressed 1023 const VkFormat blendFormats[] = 1024 { 1025 VK_FORMAT_R4G4_UNORM_PACK8, 1026 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1027 VK_FORMAT_R5G6B5_UNORM_PACK16, 1028 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 1029 VK_FORMAT_R8_UNORM, 1030 VK_FORMAT_R8_SNORM, 1031 VK_FORMAT_R8_SRGB, 1032 VK_FORMAT_R8G8_UNORM, 1033 VK_FORMAT_R8G8_SNORM, 1034 VK_FORMAT_R8G8_SRGB, 1035 VK_FORMAT_R8G8B8_UNORM, 1036 VK_FORMAT_R8G8B8_SNORM, 1037 VK_FORMAT_R8G8B8_SRGB, 1038 VK_FORMAT_R8G8B8A8_UNORM, 1039 VK_FORMAT_R8G8B8A8_SNORM, 1040 VK_FORMAT_R8G8B8A8_SRGB, 1041 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 1042 VK_FORMAT_R16_UNORM, 1043 VK_FORMAT_R16_SNORM, 1044 VK_FORMAT_R16_SFLOAT, 1045 VK_FORMAT_R16G16_UNORM, 1046 VK_FORMAT_R16G16_SNORM, 1047 VK_FORMAT_R16G16_SFLOAT, 1048 VK_FORMAT_R16G16B16_UNORM, 1049 VK_FORMAT_R16G16B16_SNORM, 1050 VK_FORMAT_R16G16B16_SFLOAT, 1051 VK_FORMAT_R16G16B16A16_UNORM, 1052 VK_FORMAT_R16G16B16A16_SNORM, 1053 VK_FORMAT_R16G16B16A16_SFLOAT, 1054 VK_FORMAT_R32_SFLOAT, 1055 VK_FORMAT_R32G32_SFLOAT, 1056 VK_FORMAT_R32G32B32_SFLOAT, 1057 VK_FORMAT_R32G32B32A32_SFLOAT, 1058 VK_FORMAT_B10G11R11_UFLOAT_PACK32, 1059 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, 1060 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1061 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 1062 }; 1063 1064 de::MovePtr<tcu::TestCaseGroup> blendTests (new tcu::TestCaseGroup(testCtx, "blend", "Blend tests")); 1065 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats")); 1066 BlendStateUniqueRandomIterator blendStateItr (blendStatesPerFormat, 123); 1067 1068 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++) 1069 { 1070 const VkFormat format = blendFormats[formatNdx]; 1071 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx, 1072 getFormatCaseName(format).c_str(), 1073 (std::string("Uses format ") + getFormatName(format)).c_str())); 1074 de::MovePtr<tcu::TestCaseGroup> blendStateTests; 1075 { 1076 std::ostringstream blendStateDescription; 1077 blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst; 1078 blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str())); 1079 } 1080 1081 blendStateItr.reset(); 1082 1083 while (blendStateItr.hasNext()) 1084 { 1085 VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT]; 1086 1087 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++) 1088 { 1089 quadBlendConfigs[quadNdx] = blendStateItr.next(); 1090 quadBlendConfigs[quadNdx].colorWriteMask = BlendTest::s_colorWriteMasks[quadNdx]; 1091 } 1092 1093 blendStateTests->addChild(new BlendTest(testCtx, 1094 getBlendStateSetName(quadBlendConfigs), 1095 getBlendStateSetDescription(quadBlendConfigs), 1096 format, 1097 quadBlendConfigs)); 1098 } 1099 formatTest->addChild(blendStateTests.release()); 1100 formatTests->addChild(formatTest.release()); 1101 } 1102 blendTests->addChild(formatTests.release()); 1103 1104 return blendTests.release(); 1105} 1106 1107} // pipeline 1108} // vkt 1109