1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2020 The Khronos Group Inc. 6 * Copyright (c) 2020 Valve Corporation. 7 * Copyright (c) 2023 LunarG, Inc. 8 * Copyright (c) 2023 Nintendo 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 *//*! 23 * \file 24 * \brief Logic Operators Tests 25 *//*--------------------------------------------------------------------*/ 26 27#include "vktPipelineLogicOpTests.hpp" 28#include "vktPipelineImageUtil.hpp" 29 30#include "vkQueryUtil.hpp" 31#include "vkCmdUtil.hpp" 32#include "vkObjUtil.hpp" 33#include "vkTypeUtil.hpp" 34#include "vkMemUtil.hpp" 35#include "vkImageUtil.hpp" 36#include "vkImageWithMemory.hpp" 37 38#include "tcuVectorUtil.hpp" 39#include "tcuImageCompare.hpp" 40#include "tcuTestLog.hpp" 41 42#include <string> 43#include <limits> 44 45namespace vkt 46{ 47namespace pipeline 48{ 49 50using namespace vk; 51 52namespace 53{ 54 55bool isSupportedColorAttachmentFormat (const InstanceInterface& instanceInterface, 56 VkPhysicalDevice device, 57 VkFormat format) 58{ 59 VkFormatProperties formatProps; 60 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps); 61 62 // Format also needs to be INT, UINT, or SINT but as we are the ones setting the 63 // color attachment format we only need to check that it is a valid color attachment 64 // format here. 65 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT); 66} 67 68struct TestParams 69{ 70 VkLogicOp logicOp; // Operation. 71 PipelineConstructionType pipelineConstructionType; // Use monolithic pipeline or pipeline_library 72 tcu::UVec4 fbColor; // Framebuffer color. 73 tcu::UVec4 quadColor; // Geometry color. 74 VkFormat format; // Framebuffer format. 75 std::string name; // Logic operator test name. 76}; 77 78deUint32 calcOpResult(VkLogicOp op, deUint32 src, deUint32 dst) 79{ 80 // See section 29.2 "Logical Operations" in the spec. 81 // 82 // AND: SRC & DST = 1010 & 1100 = 1000 = 0x8 83 // AND_REVERSE: SRC & ~DST = 0011 & 1010 = 0010 = 0x2 84 // COPY: SRC = 1010 = 1010 = 0xa 85 // AND_INVERTED: ~SRC & DST = 0101 & 1100 = 0100 = 0x4 86 // NO_OP: DST = 1010 = 1010 = 0xa 87 // XOR: SRC ^ DST = 1010 ^ 1100 = 0110 = 0x6 88 // OR: SRC | DST = 1010 | 1100 = 1110 = 0xe 89 // NOR: ~(SRC | DST) = ~(1010 | 1100) = 0001 = 0x1 90 // EQUIVALENT: ~(SRC ^ DST) = ~(1010 ^ 1100) = 1001 = 0x9 91 // INVERT: ~DST = ~1100 = 0011 = 0x3 92 // OR_REVERSE: SRC | ~DST = 1010 | 0011 = 1011 = 0xb 93 // COPY_INVERTED: ~SRC = 0101 = 0101 = 0x5 94 // OR_INVERTED: ~SRC | DST = 0101 | 1100 = 1101 = 0xd 95 // NAND: ~(SRC & DST) = ~(1010 &1100) = 0111 = 0x7 96 // SET: = 1111 = 1111 = 0xf (sets all bits) 97 98 switch (op) 99 { 100 case VK_LOGIC_OP_CLEAR: return (0u); 101 case VK_LOGIC_OP_AND: return (src & dst); 102 case VK_LOGIC_OP_AND_REVERSE: return (src & ~dst); 103 case VK_LOGIC_OP_COPY: return (src); 104 case VK_LOGIC_OP_AND_INVERTED: return (~src & dst); 105 case VK_LOGIC_OP_NO_OP: return (dst); 106 case VK_LOGIC_OP_XOR: return (src ^ dst); 107 case VK_LOGIC_OP_OR: return (src | dst); 108 case VK_LOGIC_OP_NOR: return (~(src | dst)); 109 case VK_LOGIC_OP_EQUIVALENT: return (~(src ^ dst)); 110 case VK_LOGIC_OP_INVERT: return (~dst); 111 case VK_LOGIC_OP_OR_REVERSE: return (src | ~dst); 112 case VK_LOGIC_OP_COPY_INVERTED: return (~src); 113 case VK_LOGIC_OP_OR_INVERTED: return (~src | dst); 114 case VK_LOGIC_OP_NAND: return (~(src & dst)); 115 case VK_LOGIC_OP_SET: return (std::numeric_limits<deUint32>::max()); 116 default: DE_ASSERT(false); break; 117 } 118 119 DE_ASSERT(false); 120 return 0u; 121} 122 123// Gets a bitmask to filter out unused bits according to the channel size (e.g. 0xFFu for 8-bit channels). 124// channelSize in bytes. 125deUint32 getChannelMask (int channelSize) 126{ 127 DE_ASSERT(channelSize >= 1 && channelSize <= 4); 128 129 deUint64 mask = 1u; 130 mask <<= (channelSize * 8); 131 --mask; 132 133 return static_cast<deUint32>(mask); 134} 135 136class LogicOpTest : public vkt::TestCase 137{ 138public: 139 LogicOpTest (tcu::TestContext& testCtx, 140 const std::string& name, 141 const TestParams &testParams); 142 virtual ~LogicOpTest (void); 143 virtual void initPrograms (SourceCollections& sourceCollections) const; 144 virtual void checkSupport (Context& context) const; 145 virtual TestInstance* createInstance (Context& context) const; 146 147private: 148 TestParams m_params; 149}; 150 151LogicOpTest::LogicOpTest (tcu::TestContext& testCtx, 152 const std::string& name, 153 const TestParams& testParams) 154 : vkt::TestCase (testCtx, name) 155 , m_params (testParams) 156{ 157 DE_ASSERT(m_params.format != VK_FORMAT_UNDEFINED); 158} 159 160LogicOpTest::~LogicOpTest (void) 161{ 162} 163 164void LogicOpTest::checkSupport (Context &ctx) const 165{ 166 const auto& features = ctx.getDeviceFeatures(); 167 168 if (!features.logicOp) 169 TCU_THROW(NotSupportedError, "Logic operations not supported"); 170 171 checkPipelineConstructionRequirements(ctx.getInstanceInterface(), ctx.getPhysicalDevice(), m_params.pipelineConstructionType); 172 173 if (!isSupportedColorAttachmentFormat(ctx.getInstanceInterface(), ctx.getPhysicalDevice(), m_params.format)) 174 TCU_THROW(NotSupportedError, "Unsupported color attachment format: " + std::string(getFormatName(m_params.format))); 175} 176 177void LogicOpTest::initPrograms (SourceCollections& sourceCollections) const 178{ 179 sourceCollections.glslSources.add("color_vert") << glu::VertexSource( 180 "#version 430\n" 181 "vec2 vdata[] = vec2[] (\n" 182 "vec2(-1.0, -1.0),\n" 183 "vec2(1.0, -1.0),\n" 184 "vec2(-1.0, 1.0),\n" 185 "vec2(1.0, 1.0));\n" 186 "void main (void)\n" 187 "{\n" 188 " gl_Position = vec4(vdata[gl_VertexIndex], 0.0, 1.0);\n" 189 "}\n"); 190 191 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource( 192 "#version 430\n" 193 "layout(push_constant) uniform quadColor {\n" 194 " uvec4 val;\n" 195 "} QUAD_COLOR;\n" 196 "layout(location = 0) out uvec4 fragColor;\n" 197 "void main (void)\n" 198 "{\n" 199 " fragColor = QUAD_COLOR.val;\n" 200 "}\n"); 201} 202 203class LogicOpTestInstance : public vkt::TestInstance 204{ 205public: 206 LogicOpTestInstance(Context& context, 207 const TestParams& params); 208 ~LogicOpTestInstance(void); 209 virtual tcu::TestStatus iterate(void); 210 211private: 212 tcu::TestStatus verifyImage(void); 213 214 TestParams m_params; 215 216 // Derived from m_params. 217 const tcu::TextureFormat m_tcuFormat; 218 const int m_numChannels; 219 const int m_channelSize; 220 const deUint32 m_channelMask; 221 222 const tcu::UVec2 m_renderSize; 223 224 VkImageCreateInfo m_colorImageCreateInfo; 225 de::MovePtr<ImageWithMemory> m_colorImage; 226 Move<VkImageView> m_colorAttachmentView; 227 228 RenderPassWrapper m_renderPass; 229 Move<VkFramebuffer> m_framebuffer; 230 231 ShaderWrapper m_vertexShaderModule; 232 ShaderWrapper m_fragmentShaderModule; 233 234 PipelineLayoutWrapper m_preRasterizationStatePipelineLayout; 235 PipelineLayoutWrapper m_fragmentStatePipelineLayout; 236 GraphicsPipelineWrapper m_graphicsPipeline; 237 238 Move<VkCommandPool> m_cmdPool; 239 Move<VkCommandBuffer> m_cmdBuffer; 240}; 241 242LogicOpTestInstance::LogicOpTestInstance (Context &ctx, const TestParams &testParams) 243 : vkt::TestInstance (ctx) 244 , m_params (testParams) 245 , m_tcuFormat (mapVkFormat(m_params.format)) 246 , m_numChannels (tcu::getNumUsedChannels(m_tcuFormat.order)) 247 , m_channelSize (tcu::getChannelSize(m_tcuFormat.type)) 248 , m_channelMask (getChannelMask(m_channelSize)) 249 , m_renderSize (32u, 32u) 250 , m_graphicsPipeline (m_context.getInstanceInterface(), m_context.getDeviceInterface(), m_context.getPhysicalDevice(), m_context.getDevice(), m_context.getDeviceExtensions(), testParams.pipelineConstructionType) 251{ 252 DE_ASSERT(isUintFormat(m_params.format)); 253 254 const DeviceInterface& vk = m_context.getDeviceInterface(); 255 const VkDevice vkDevice = m_context.getDevice(); 256 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 257 Allocator& memAlloc = m_context.getDefaultAllocator(); 258 constexpr auto kPushConstantSize = static_cast<deUint32>(sizeof(m_params.quadColor)); 259 260 // create color image 261 { 262 const VkImageCreateInfo colorImageParams = 263 { 264 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 265 DE_NULL, // const void* pNext; 266 0u, // VkImageCreateFlags flags; 267 VK_IMAGE_TYPE_2D, // VkImageType imageType; 268 m_params.format, // VkFormat format; 269 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent; 270 1u, // deUint32 mipLevels; 271 1u, // deUint32 arrayLayers; 272 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 273 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 274 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; 275 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 276 1u, // deUint32 queueFamilyIndexCount; 277 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; 278 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout; 279 }; 280 281 m_colorImageCreateInfo = colorImageParams; 282 m_colorImage = de::MovePtr<ImageWithMemory>(new ImageWithMemory(vk, vkDevice, memAlloc, m_colorImageCreateInfo, MemoryRequirement::Any)); 283 284 // create color attachment view 285 const VkImageViewCreateInfo colorAttachmentViewParams = 286 { 287 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 288 DE_NULL, // const void* pNext; 289 0u, // VkImageViewCreateFlags flags; 290 m_colorImage->get(), // VkImage image; 291 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 292 m_params.format, // VkFormat format; 293 { VK_COMPONENT_SWIZZLE_IDENTITY, 294 VK_COMPONENT_SWIZZLE_IDENTITY, 295 VK_COMPONENT_SWIZZLE_IDENTITY, 296 VK_COMPONENT_SWIZZLE_IDENTITY }, 297 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange; 298 }; 299 300 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 301 } 302 303 m_renderPass = RenderPassWrapper(m_params.pipelineConstructionType, vk, vkDevice, m_params.format); 304 m_renderPass.createFramebuffer(vk, vkDevice, **m_colorImage, *m_colorAttachmentView, m_renderSize.x(), m_renderSize.y()); 305 306 // create pipeline layout 307 { 308 const VkPushConstantRange pcRange = 309 { 310 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags; 311 0u, // deUint32 offset; 312 kPushConstantSize, // deUint32 size; 313 }; 314 315#ifndef CTS_USES_VULKANSC 316 VkPipelineLayoutCreateFlags pipelineLayoutFlags = (m_params.pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT); 317#else 318 VkPipelineLayoutCreateFlags pipelineLayoutFlags = 0u; 319#endif // CTS_USES_VULKANSC 320 321 VkPipelineLayoutCreateInfo pipelineLayoutParams 322 { 323 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 324 DE_NULL, // const void* pNext; 325 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags; 326 0u, // deUint32 setLayoutCount; 327 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 328 0u, // deUint32 pushConstantRangeCount; 329 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 330 }; 331 332 m_preRasterizationStatePipelineLayout = PipelineLayoutWrapper(m_params.pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams); 333 pipelineLayoutParams.pushConstantRangeCount = 1u; 334 pipelineLayoutParams.pPushConstantRanges = &pcRange; 335 m_fragmentStatePipelineLayout = PipelineLayoutWrapper(m_params.pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams); 336 } 337 338 m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0); 339 m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0); 340 341 // create pipeline 342 { 343 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = initVulkanStructure(); 344 345 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) }; 346 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) }; 347 348 VkColorComponentFlags colorWriteMask = VK_COLOR_COMPONENT_R_BIT | 349 VK_COLOR_COMPONENT_G_BIT | 350 VK_COLOR_COMPONENT_B_BIT | 351 VK_COLOR_COMPONENT_A_BIT; 352 353 const VkPipelineColorBlendAttachmentState blendAttachmentState = 354 { 355 VK_FALSE, // VkBool32 blendEnable; 356 (VkBlendFactor) 0, // VkBlendFactor srcColorBlendFactor; 357 (VkBlendFactor) 0, // VkBlendFactor dstColorBlendFactor; 358 (VkBlendOp) 0, // VkBlendOp colorBlendOp; 359 (VkBlendFactor) 0, // VkBlendFactor srcAlphaBlendFactor; 360 (VkBlendFactor) 0, // VkBlendFactor dstAlphaBlendFactor; 361 (VkBlendOp) 0, // VkBlendOp alphaBlendOp; 362 colorWriteMask, // VkColorComponentFlags colorWriteMask; 363 }; 364 365 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams = 366 { 367 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 368 DE_NULL, // const void* pNext; 369 DE_NULL, // VkPipelineColorBlendStateCreateFlags flags; 370 VK_TRUE, // VkBool32 logicOpEnable; 371 m_params.logicOp, // VkLogicOp logicOp; 372 1u, // uint32_t attachmentCount; 373 &blendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 374 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 375 }; 376 377 m_graphicsPipeline.setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP) 378 .setDefaultDepthStencilState() 379 .setDefaultRasterizationState() 380 .setDefaultMultisampleState() 381 .setMonolithicPipelineLayout(m_fragmentStatePipelineLayout) 382 .setupVertexInputState(&vertexInputStateParams) 383 .setupPreRasterizationShaderState(viewports, 384 scissors, 385 m_preRasterizationStatePipelineLayout, 386 *m_renderPass, 387 0u, 388 m_vertexShaderModule) 389 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule) 390 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams) 391 .buildPipeline(); 392 } 393 394 // create command pool 395 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 396 397 // allocate and record command buffer 398 { 399 // Prepare clear color value and quad color taking into account the channel mask. 400 VkClearValue attachmentClearValue; 401 tcu::UVec4 quadColor(0u, 0u, 0u, 0u); 402 403 deMemset(&attachmentClearValue.color, 0, sizeof(attachmentClearValue.color)); 404 for (int c = 0; c < m_numChannels; ++c) 405 attachmentClearValue.color.uint32[c] = (m_params.fbColor[c] & m_channelMask); 406 407 for (int c = 0; c < m_numChannels; ++c) 408 quadColor[c] = (m_params.quadColor[c] & m_channelMask); 409 410 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 411 412 beginCommandBuffer(vk, *m_cmdBuffer, 0u); 413 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), attachmentClearValue); 414 415 // Update push constant values 416 vk.cmdPushConstants(*m_cmdBuffer, *m_fragmentStatePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, kPushConstantSize, &quadColor); 417 418 m_graphicsPipeline.bind(*m_cmdBuffer); 419 vk.cmdDraw(*m_cmdBuffer, 4u, 1u, 0u, 0u); 420 m_renderPass.end(vk, *m_cmdBuffer); 421 endCommandBuffer(vk, *m_cmdBuffer); 422 } 423} 424 425LogicOpTestInstance::~LogicOpTestInstance (void) 426{ 427} 428 429tcu::TestStatus LogicOpTestInstance::iterate (void) 430{ 431 const DeviceInterface& vk = m_context.getDeviceInterface(); 432 const VkDevice vkDevice = m_context.getDevice(); 433 const VkQueue queue = m_context.getUniversalQueue(); 434 435 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 436 return verifyImage(); 437} 438 439tcu::TestStatus LogicOpTestInstance::verifyImage (void) 440{ 441 const DeviceInterface& vk = m_context.getDeviceInterface(); 442 const VkDevice vkDevice = m_context.getDevice(); 443 const VkQueue queue = m_context.getUniversalQueue(); 444 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 445 Allocator& allocator = m_context.getDefaultAllocator(); 446 auto& log = m_context.getTestContext().getLog(); 447 448 const auto result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, m_colorImage->get(), m_params.format, m_renderSize).release(); 449 const auto resultAccess = result->getAccess(); 450 const int iWidth = static_cast<int>(m_renderSize.x()); 451 const int iHeight = static_cast<int>(m_renderSize.y()); 452 tcu::UVec4 expectedColor (0u, 0u, 0u, 0u); // Overwritten below. 453 tcu::TextureLevel referenceTexture (m_tcuFormat, iWidth, iHeight); 454 auto referenceAccess = referenceTexture.getAccess(); 455 tcu::UVec4 threshold (0u, 0u, 0u, 0u); // Exact results. 456 457 // Calculate proper expected color values. 458 for (int c = 0; c < m_numChannels; ++c) 459 { 460 expectedColor[c] = calcOpResult(m_params.logicOp, m_params.quadColor[c], m_params.fbColor[c]); 461 expectedColor[c] &= m_channelMask; 462 } 463 464 for (int y = 0; y < iHeight; ++y) 465 for (int x = 0; x < iWidth; ++x) 466 referenceAccess.setPixel(expectedColor, x, y); 467 468 // Check result. 469 bool resultOk = tcu::intThresholdCompare(log, "TestResults", "Test Result Images", referenceAccess, resultAccess, threshold, tcu::COMPARE_LOG_ON_ERROR); 470 471 if (!resultOk) 472 TCU_FAIL("Result does not match expected values; check log for details"); 473 474 return tcu::TestStatus::pass("Pass"); 475} 476 477TestInstance *LogicOpTest::createInstance (Context& context) const 478{ 479 return new LogicOpTestInstance(context, m_params); 480} 481 482std::string getSimpleFormatName (VkFormat format) 483{ 484 return de::toLower(std::string(getFormatName(format)).substr(std::string("VK_FORMAT_").size())); 485} 486 487} // anonymous namespace 488 489tcu::TestCaseGroup* createLogicOpTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineType) 490{ 491 de::MovePtr<tcu::TestCaseGroup> logicOpTests (new tcu::TestCaseGroup(testCtx, "logic_op")); 492 493 // 4 bits are enough to check all possible combinations of logical operation inputs at once, for example s AND d: 494 // 495 // 1 0 1 0 496 // AND 1 1 0 0 497 // ------------ 498 // 1 0 0 0 499 // 500 // However, we will choose color values such that both higher bits and lower bits are used, and the implementation will not be 501 // able to mix channels by mistake. 502 // 503 // 0011 0101 1010 1100 504 // 3 5 a c 505 // 0101 0011 1100 1010 506 // 5 3 c a 507 508 const tcu::UVec4 kQuadColor = { 0x35acU, 0x5ac3U, 0xac35U, 0xc35aU }; 509 const tcu::UVec4 kFbColor = { 0x53caU, 0x3ca5U, 0xca53U, 0xa53cU }; 510 511 // Note: the format will be chosen and changed later. 512 std::vector<TestParams> logicOpTestParams 513 { 514 { VK_LOGIC_OP_CLEAR, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "clear" }, 515 { VK_LOGIC_OP_AND, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "and" }, 516 { VK_LOGIC_OP_AND_REVERSE, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "and_reverse" }, 517 { VK_LOGIC_OP_COPY, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "copy" }, 518 { VK_LOGIC_OP_AND_INVERTED, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "and_inverted" }, 519 { VK_LOGIC_OP_NO_OP, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "no_op" }, 520 { VK_LOGIC_OP_XOR, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "xor" }, 521 { VK_LOGIC_OP_OR, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "or" }, 522 { VK_LOGIC_OP_NOR, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "nor" }, 523 { VK_LOGIC_OP_EQUIVALENT, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "equivalent" }, 524 { VK_LOGIC_OP_INVERT, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "invert" }, 525 { VK_LOGIC_OP_OR_REVERSE, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "or_reverse" }, 526 { VK_LOGIC_OP_COPY_INVERTED, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "copy_inverted" }, 527 { VK_LOGIC_OP_OR_INVERTED, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "or_inverted" }, 528 { VK_LOGIC_OP_NAND, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "nand" }, 529 { VK_LOGIC_OP_SET, pipelineType, kFbColor, kQuadColor, VK_FORMAT_UNDEFINED, "set" }, 530 }; 531 532 const VkFormat formatList[] = 533 { 534 VK_FORMAT_R8_UINT, 535 VK_FORMAT_R8G8_UINT, 536 VK_FORMAT_R8G8B8_UINT, 537 VK_FORMAT_B8G8R8_UINT, 538 VK_FORMAT_R8G8B8A8_UINT, 539 VK_FORMAT_B8G8R8A8_UINT, 540 VK_FORMAT_R16_UINT, 541 VK_FORMAT_R16G16_UINT, 542 VK_FORMAT_R16G16B16_UINT, 543 VK_FORMAT_R16G16B16A16_UINT, 544 VK_FORMAT_R32_UINT, 545 VK_FORMAT_R32G32_UINT, 546 VK_FORMAT_R32G32B32_UINT, 547 VK_FORMAT_R32G32B32A32_UINT, 548 }; 549 550 for (int formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(formatList); ++formatIdx) 551 { 552 const auto& format = formatList[formatIdx]; 553 const auto formatName = getSimpleFormatName(format); 554 const auto formatDesc = "Logical operator tests with format " + formatName; 555 556 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, formatName.c_str())); 557 558 for (auto& params : logicOpTestParams) 559 { 560 params.format = format; 561 formatGroup->addChild(new LogicOpTest(testCtx, params.name, params)); 562 } 563 564 logicOpTests->addChild(formatGroup.release()); 565 } 566 567 return logicOpTests.release(); 568} 569 570} // pipeline namespace 571} // vkt namespace 572