1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
34 *//*--------------------------------------------------------------------*/
36 #include "vktPipelineBlendTests.hpp"
37 #include "vktPipelineClearUtil.hpp"
38 #include "vktPipelineImageUtil.hpp"
39 #include "vktPipelineVertexUtil.hpp"
40 #include "vktPipelineUniqueRandomIterator.hpp"
41 #include "vktPipelineReferenceRenderer.hpp"
42 #include "vktTestCase.hpp"
43 #include "vkImageUtil.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkPlatform.hpp"
46 #include "vkPrograms.hpp"
47 #include "vkQueryUtil.hpp"
49 #include "vkRefUtil.hpp"
50 #include "tcuImageCompare.hpp"
51 #include "tcuPlatform.hpp"
52 #include "tcuTextureUtil.hpp"
53 #include "deRandom.hpp"
54 #include "deStringUtil.hpp"
55 #include "deUniquePtr.hpp"
71 bool isSupportedBlendFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
73 VkFormatProperties formatProps;
75 instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
77 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) &&
78 (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
81 class BlendStateUniqueRandomIterator : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState>
84 BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed);
85 virtual ~BlendStateUniqueRandomIterator (void) {}
86 VkPipelineColorBlendAttachmentState getIndexedValue (deUint32 index);
89 const static VkBlendFactor m_blendFactors[];
90 const static VkBlendOp m_blendOps[];
92 // Pre-calculated constants
93 const static deUint32 m_blendFactorsLength;
94 const static deUint32 m_blendFactorsLength2;
95 const static deUint32 m_blendFactorsLength3;
96 const static deUint32 m_blendFactorsLength4;
97 const static deUint32 m_blendOpsLength;
99 // Total number of cross-combinations of (srcBlendColor x destBlendColor x blendOpColor x srcBlendAlpha x destBlendAlpha x blendOpAlpha)
100 const static deUint32 m_totalBlendStates;
103 class BlendTest : public vkt::TestCase
111 const static VkColorComponentFlags s_colorWriteMasks[QUAD_COUNT];
112 const static tcu::Vec4 s_blendConst;
114 BlendTest (tcu::TestContext& testContext,
115 const std::string& name,
116 const std::string& description,
117 const VkFormat colorFormat,
118 const VkPipelineColorBlendAttachmentState blendStates[QUAD_COUNT]);
119 virtual ~BlendTest (void);
120 virtual void initPrograms (SourceCollections& sourceCollections) const;
121 virtual TestInstance* createInstance (Context& context) const;
124 const VkFormat m_colorFormat;
125 VkPipelineColorBlendAttachmentState m_blendStates[QUAD_COUNT];
128 class BlendTestInstance : public vkt::TestInstance
131 BlendTestInstance (Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]);
132 virtual ~BlendTestInstance (void);
133 virtual tcu::TestStatus iterate (void);
136 static float getNormChannelThreshold (const tcu::TextureFormat& format, int numBits);
137 static tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format);
138 tcu::TestStatus verifyImage (void);
140 VkPipelineColorBlendAttachmentState m_blendStates[BlendTest::QUAD_COUNT];
142 const tcu::IVec2 m_renderSize;
143 const VkFormat m_colorFormat;
145 VkImageCreateInfo m_colorImageCreateInfo;
146 Move<VkImage> m_colorImage;
147 de::MovePtr<Allocation> m_colorImageAlloc;
148 Move<VkImageView> m_colorAttachmentView;
149 Move<VkRenderPass> m_renderPass;
150 Move<VkFramebuffer> m_framebuffer;
152 Move<VkShaderModule> m_vertexShaderModule;
153 Move<VkShaderModule> m_fragmentShaderModule;
155 Move<VkBuffer> m_vertexBuffer;
156 std::vector<Vertex4RGBA> m_vertices;
157 de::MovePtr<Allocation> m_vertexBufferAlloc;
159 Move<VkPipelineLayout> m_pipelineLayout;
160 Move<VkPipeline> m_graphicsPipelines[BlendTest::QUAD_COUNT];
162 Move<VkCommandPool> m_cmdPool;
163 Move<VkCommandBuffer> m_cmdBuffer;
165 Move<VkFence> m_fence;
169 // BlendStateUniqueRandomIterator
171 const VkBlendFactor BlendStateUniqueRandomIterator::m_blendFactors[] =
173 VK_BLEND_FACTOR_ZERO,
175 VK_BLEND_FACTOR_SRC_COLOR,
176 VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR,
177 VK_BLEND_FACTOR_DST_COLOR,
178 VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR,
179 VK_BLEND_FACTOR_SRC_ALPHA,
180 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
181 VK_BLEND_FACTOR_DST_ALPHA,
182 VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA,
183 VK_BLEND_FACTOR_CONSTANT_COLOR,
184 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR,
185 VK_BLEND_FACTOR_CONSTANT_ALPHA,
186 VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA,
187 VK_BLEND_FACTOR_SRC_ALPHA_SATURATE
190 const VkBlendOp BlendStateUniqueRandomIterator::m_blendOps[] =
193 VK_BLEND_OP_SUBTRACT,
194 VK_BLEND_OP_REVERSE_SUBTRACT,
199 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength = DE_LENGTH_OF_ARRAY(m_blendFactors);
200 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength2 = m_blendFactorsLength * m_blendFactorsLength;
201 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength3 = m_blendFactorsLength2 * m_blendFactorsLength;
202 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength4 = m_blendFactorsLength3 * m_blendFactorsLength;
203 const deUint32 BlendStateUniqueRandomIterator::m_blendOpsLength = DE_LENGTH_OF_ARRAY(m_blendOps);
204 const deUint32 BlendStateUniqueRandomIterator::m_totalBlendStates = m_blendFactorsLength4 * m_blendOpsLength * m_blendOpsLength;
207 BlendStateUniqueRandomIterator::BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed)
208 : UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed)
212 VkPipelineColorBlendAttachmentState BlendStateUniqueRandomIterator::getIndexedValue (deUint32 index)
214 const deUint32 blendOpAlphaIndex = index / (m_blendFactorsLength4 * m_blendOpsLength);
215 const deUint32 blendOpAlphaSeqIndex = blendOpAlphaIndex * (m_blendFactorsLength4 * m_blendOpsLength);
217 const deUint32 destBlendAlphaIndex = (index - blendOpAlphaSeqIndex) / (m_blendFactorsLength3 * m_blendOpsLength);
218 const deUint32 destBlendAlphaSeqIndex = destBlendAlphaIndex * (m_blendFactorsLength3 * m_blendOpsLength);
220 const deUint32 srcBlendAlphaIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex) / (m_blendFactorsLength2 * m_blendOpsLength);
221 const deUint32 srcBlendAlphaSeqIndex = srcBlendAlphaIndex * (m_blendFactorsLength2 * m_blendOpsLength);
223 const deUint32 blendOpColorIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex) / m_blendFactorsLength2;
224 const deUint32 blendOpColorSeqIndex = blendOpColorIndex * m_blendFactorsLength2;
226 const deUint32 destBlendColorIndex = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex) / m_blendFactorsLength;
227 const deUint32 destBlendColorSeqIndex = destBlendColorIndex * m_blendFactorsLength;
229 const deUint32 srcBlendColorIndex = index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex - destBlendColorSeqIndex;
231 const VkPipelineColorBlendAttachmentState blendAttachmentState =
233 true, // VkBool32 blendEnable;
234 m_blendFactors[srcBlendColorIndex], // VkBlendFactor srcColorBlendFactor;
235 m_blendFactors[destBlendColorIndex], // VkBlendFactor dstColorBlendFactor;
236 m_blendOps[blendOpColorIndex], // VkBlendOp colorBlendOp;
237 m_blendFactors[srcBlendAlphaIndex], // VkBlendFactor srcAlphaBlendFactor;
238 m_blendFactors[destBlendAlphaIndex], // VkBlendFactor dstAlphaBlendFactor;
239 m_blendOps[blendOpAlphaIndex], // VkBlendOp alphaBlendOp;
240 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
241 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
244 return blendAttachmentState;
250 const VkColorComponentFlags BlendTest::s_colorWriteMasks[BlendTest::QUAD_COUNT] = { VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT, // Pair of channels: R & G
251 VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT, // Pair of channels: G & B
252 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT, // Pair of channels: B & A
253 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT }; // All channels
255 const tcu::Vec4 BlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);
257 BlendTest::BlendTest (tcu::TestContext& testContext,
258 const std::string& name,
259 const std::string& description,
260 const VkFormat colorFormat,
261 const VkPipelineColorBlendAttachmentState blendStates[QUAD_COUNT])
262 : vkt::TestCase (testContext, name, description)
263 , m_colorFormat(colorFormat)
265 deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * QUAD_COUNT);
268 BlendTest::~BlendTest (void)
272 TestInstance* BlendTest::createInstance(Context& context) const
274 return new BlendTestInstance(context, m_colorFormat, m_blendStates);
277 void BlendTest::initPrograms (SourceCollections& sourceCollections) const
279 std::ostringstream fragmentSource;
281 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
283 "layout(location = 0) in highp vec4 position;\n"
284 "layout(location = 1) in highp vec4 color;\n"
285 "layout(location = 0) out highp vec4 vtxColor;\n"
288 " gl_Position = position;\n"
289 " vtxColor = color;\n"
292 fragmentSource << "#version 310 es\n"
293 "layout(location = 0) in highp vec4 vtxColor;\n"
294 "layout(location = 0) out highp vec4 fragColor;\n"
297 " fragColor = vtxColor;\n"
300 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
306 BlendTestInstance::BlendTestInstance (Context& context,
307 const VkFormat colorFormat,
308 const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
309 : vkt::TestInstance (context)
310 , m_renderSize (32, 32)
311 , m_colorFormat (colorFormat)
313 const DeviceInterface& vk = m_context.getDeviceInterface();
314 const VkDevice vkDevice = m_context.getDevice();
315 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
316 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
318 // Copy depth operators
319 deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * BlendTest::QUAD_COUNT);
321 // Create color image
323 if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_colorFormat))
324 throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_colorFormat));
326 const VkImageCreateInfo colorImageParams =
328 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
329 DE_NULL, // const void* pNext;
330 0u, // VkImageCreateFlags flags;
331 VK_IMAGE_TYPE_2D, // VkImageType imageType;
332 m_colorFormat, // VkFormat format;
333 { m_renderSize.x(), m_renderSize.y(), 1u }, // VkExtent3D extent;
334 1u, // deUint32 mipLevels;
335 1u, // deUint32 arrayLayers;
336 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
337 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
338 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
339 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
340 1u, // deUint32 queueFamilyIndexCount;
341 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
342 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
345 m_colorImageCreateInfo = colorImageParams;
346 m_colorImage = createImage(vk, vkDevice, &m_colorImageCreateInfo);
348 // Allocate and bind color image memory
349 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
350 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
353 // Create color attachment view
355 const VkImageViewCreateInfo colorAttachmentViewParams =
357 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
358 DE_NULL, // const void* pNext;
359 0u, // VkImageViewCreateFlags flags;
360 *m_colorImage, // VkImage image;
361 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
362 m_colorFormat, // VkFormat format;
363 getFormatComponentMapping(m_colorFormat), // VkComponentMapping components;
364 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
367 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
370 // Create render pass
372 const VkAttachmentDescription colorAttachmentDescription =
374 0u, // VkAttachmentDescriptionFlags flags;
375 m_colorFormat, // VkFormat format;
376 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
377 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
378 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
379 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
380 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
381 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
382 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
385 const VkAttachmentReference colorAttachmentReference =
387 0u, // deUint32 attachment;
388 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
391 const VkSubpassDescription subpassDescription =
393 0u, // VkSubpassDescriptionFlag flags;
394 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
395 0u, // deUint32 inputAttachmentCount;
396 DE_NULL, // const VkAttachmentReference* pInputAttachments;
397 1u, // deUint32 colorAttachmentCount;
398 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
399 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
400 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
401 0u, // deUint32 preserveAttachmentCount;
402 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
405 const VkRenderPassCreateInfo renderPassParams =
407 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
408 DE_NULL, // const void* pNext;
409 0u, // VkRenderPassCreateFlags flags;
410 1u, // deUint32 attachmentCount;
411 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
412 1u, // deUint32 subpassCount;
413 &subpassDescription, // const VkSubpassDescription* pSubpasses;
414 0u, // deUint32 dependencyCount;
415 DE_NULL // const VkSubpassDependency* pDependencies;
418 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
421 // Create framebuffer
423 const VkFramebufferCreateInfo framebufferParams =
425 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
426 DE_NULL, // const void* pNext;
427 0u, // VkFramebufferCreateFlags flags;
428 *m_renderPass, // VkRenderPass renderPass;
429 1u, // deUint32 attachmentCount;
430 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
431 (deUint32)m_renderSize.x(), // deUint32 width;
432 (deUint32)m_renderSize.y(), // deUint32 height;
433 1u // deUint32 layers;
436 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
439 // Create pipeline layout
441 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
443 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
444 DE_NULL, // const void* pNext;
445 0u, // VkPipelineLayoutCreateFlags flags;
446 0u, // deUint32 setLayoutCount;
447 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
448 0u, // deUint32 pushConstantRangeCount;
449 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
452 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
455 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
456 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
460 const VkPipelineShaderStageCreateInfo shaderStages[2] =
463 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
464 DE_NULL, // const void* pNext;
465 0u, // VkPipelineShaderStageCreateFlags flags;
466 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
467 *m_vertexShaderModule, // VkShaderModule module;
468 "main", // const char* pName;
469 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
472 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
473 DE_NULL, // const void* pNext;
474 0u, // VkPipelineShaderStageCreateFlags flags;
475 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
476 *m_fragmentShaderModule, // VkShaderModule module;
477 "main", // const char* pName;
478 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
482 const VkVertexInputBindingDescription vertexInputBindingDescription =
484 0u, // deUint32 binding;
485 sizeof(Vertex4RGBA), // deUint32 strideInBytes;
486 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
489 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
492 0u, // deUint32 location;
493 0u, // deUint32 binding;
494 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
495 0u // deUint32 offset;
498 1u, // deUint32 location;
499 0u, // deUint32 binding;
500 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
501 (deUint32)(sizeof(float) * 4), // deUint32 offset;
505 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
507 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
508 DE_NULL, // const void* pNext;
509 0u, // VkPipelineVertexInputStateCreateFlags flags;
510 1u, // deUint32 vertexBindingDescriptionCount;
511 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
512 2u, // deUint32 vertexAttributeDescriptionCount;
513 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
516 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
518 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
519 DE_NULL, // const void* pNext;
520 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
521 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
522 false // VkBool32 primitiveRestartEnable;
525 const VkViewport viewport =
529 (float)m_renderSize.x(), // float width;
530 (float)m_renderSize.y(), // float height;
531 0.0f, // float minDepth;
532 1.0f // float maxDepth;
535 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
537 const VkPipelineViewportStateCreateInfo viewportStateParams =
539 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
540 DE_NULL, // const void* pNext;
541 0u, // VkPipelineViewportStateCreateFlags flags;
542 1u, // deUint32 viewportCount;
543 &viewport, // const VkViewport* pViewports;
544 1u, // deUint32 scissorCount;
545 &scissor // const VkRect2D* pScissors;
548 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
550 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
551 DE_NULL, // const void* pNext;
552 0u, // VkPipelineRasterizationStateCreateFlags flags;
553 false, // VkBool32 depthClampEnable;
554 false, // VkBool32 rasterizerDiscardEnable;
555 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
556 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
557 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
558 false, // VkBool32 depthBiasEnable;
559 0.0f, // float depthBiasConstantFactor;
560 0.0f, // float depthBiasClamp;
561 0.0f, // float depthBiasSlopeFactor;
562 1.0f // float lineWidth;
565 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
567 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
568 DE_NULL, // const void* pNext;
569 0u, // VkPipelineMultisampleStateCreateFlags flags;
570 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
571 false, // VkBool32 sampleShadingEnable;
572 0.0f, // float minSampleShading;
573 DE_NULL, // const VkSampleMask* pSampleMask;
574 false, // VkBool32 alphaToCoverageEnable;
575 false // VkBool32 alphaToOneEnable;
578 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
580 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
581 DE_NULL, // const void* pNext;
582 0u, // VkPipelineDepthStencilStateCreateFlags flags;
583 false, // VkBool32 depthTestEnable;
584 false, // VkBool32 depthWriteEnable;
585 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
586 false, // VkBool32 depthBoundsTestEnable;
587 false, // VkBool32 stencilTestEnable;
588 // VkStencilOpState front;
590 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
591 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
592 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
593 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
594 0u, // deUint32 compareMask;
595 0u, // deUint32 writeMask;
596 0u // deUint32 reference;
598 // VkStencilOpState back;
600 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
601 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
602 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
603 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
604 0u, // deUint32 compareMask;
605 0u, // deUint32 writeMask;
606 0u // deUint32 reference;
608 -1.0f, // float minDepthBounds;
609 +1.0f // float maxDepthBounds;
612 // The color blend attachment will be set up before creating the graphics pipeline.
613 VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
615 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
616 DE_NULL, // const void* pNext;
617 0u, // VkPipelineColorBlendStateCreateFlags flags;
618 false, // VkBool32 logicOpEnable;
619 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
620 0u, // deUint32 attachmentCount;
621 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
622 { // float blendConstants[4];
623 BlendTest::s_blendConst.x(),
624 BlendTest::s_blendConst.y(),
625 BlendTest::s_blendConst.z(),
626 BlendTest::s_blendConst.w()
630 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
632 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, // VkStructureType sType;
633 DE_NULL, // const void* pNext;
634 0u, // VkPipelineDynamicStateCreateFlags flags;
635 0u, // deUint32 dynamicStateCount;
636 DE_NULL // const VkDynamicState* pDynamicStates;
639 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
641 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
642 DE_NULL, // const void* pNext;
643 0u, // VkPipelineCreateFlags flags;
644 2u, // deUint32 stageCount;
645 shaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
646 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
647 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
648 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
649 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
650 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
651 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
652 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
653 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
654 &dynamicStateParams, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
655 *m_pipelineLayout, // VkPipelineLayout layout;
656 *m_renderPass, // VkRenderPass renderPass;
657 0u, // deUint32 subpass;
658 0u, // VkPipeline basePipelineHandle;
659 0u // deInt32 basePipelineIndex;
662 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
664 colorBlendStateParams.attachmentCount = 1u;
665 colorBlendStateParams.pAttachments = &m_blendStates[quadNdx];
666 m_graphicsPipelines[quadNdx] = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
670 // Create vertex buffer
672 const VkBufferCreateInfo vertexBufferParams =
674 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
675 DE_NULL, // const void* pNext;
676 0u, // VkBufferCreateFlags flags;
677 1024u, // VkDeviceSize size;
678 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
679 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
680 1u, // deUint32 queueFamilyIndexCount;
681 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
684 m_vertices = createOverlappingQuads();
685 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
686 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
688 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
690 // Adjust vertex colors
691 if (!isFloatFormat(m_colorFormat))
693 const tcu::TextureFormatInfo formatInfo = tcu::getTextureFormatInfo(mapVkFormat(m_colorFormat));
694 for (size_t vertexNdx = 0; vertexNdx < m_vertices.size(); vertexNdx++)
695 m_vertices[vertexNdx].color = (m_vertices[vertexNdx].color - formatInfo.lookupBias) / formatInfo.lookupScale;
698 // Upload vertex data
699 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
701 const VkMappedMemoryRange flushRange =
703 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // VkStructureType sType;
704 DE_NULL, // const void* pNext;
705 m_vertexBufferAlloc->getMemory(), // VkDeviceMemory memory;
706 m_vertexBufferAlloc->getOffset(), // VkDeviceSize offset;
707 vertexBufferParams.size // VkDeviceSize size;
710 vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange);
713 // Create command pool
715 const VkCommandPoolCreateInfo cmdPoolParams =
717 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
718 DE_NULL, // const void* pNext;
719 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
720 queueFamilyIndex // deUint32 queueFamilyIndex;
723 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
726 // Create command buffer
728 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
730 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
731 DE_NULL, // const void* pNext;
732 *m_cmdPool, // VkCommandPool commandPool;
733 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
734 1u, // deUint32 bufferCount;
737 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
739 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
740 DE_NULL, // const void* pNext;
741 0u, // VkCommandBufferUsageFlags flags;
742 DE_NULL, // VkRenderPass renderPass;
743 0u, // deUint32 subpass;
744 DE_NULL, // VkFramebuffer framebuffer;
745 false, // VkBool32 occlusionQueryEnable;
746 0u, // VkQueryControlFlags queryFlags;
747 0u // VkQueryPipelineStatisticFlags pipelineStatistics;
750 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
752 const VkRenderPassBeginInfo renderPassBeginInfo =
754 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
755 DE_NULL, // const void* pNext;
756 *m_renderPass, // VkRenderPass renderPass;
757 *m_framebuffer, // VkFramebuffer framebuffer;
758 { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } }, // VkRect2D renderArea;
759 1, // deUint32 clearValueCount;
760 &attachmentClearValue // const VkClearValue* pClearValues;
763 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
765 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
766 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
768 const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
770 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
772 VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
774 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
775 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
776 vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / BlendTest::QUAD_COUNT), 1, 0, 0);
779 vk.cmdEndRenderPass(*m_cmdBuffer);
780 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
785 const VkFenceCreateInfo fenceParams =
787 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
788 DE_NULL, // const void* pNext;
789 0u // VkFenceCreateFlags flags;
792 m_fence = createFence(vk, vkDevice, &fenceParams);
796 BlendTestInstance::~BlendTestInstance (void)
800 tcu::TestStatus BlendTestInstance::iterate (void)
802 const DeviceInterface& vk = m_context.getDeviceInterface();
803 const VkDevice vkDevice = m_context.getDevice();
804 const VkQueue queue = m_context.getUniversalQueue();
805 const VkSubmitInfo submitInfo =
807 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
808 DE_NULL, // const void* pNext;
809 0u, // deUint32 waitSemaphoreCount;
810 DE_NULL, // const VkSemaphore* pWaitSemaphores;
811 1u, // deUint32 commandBufferCount;
812 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
813 0u, // deUint32 signalSemaphoreCount;
814 DE_NULL // const VkSemaphore* pSignalSemaphores;
817 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
818 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
819 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
821 return verifyImage();
824 float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
826 switch (tcu::getTextureChannelClass(format.type))
828 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT: return BlendTest::QUAD_COUNT / static_cast<float>((1 << numBits) - 1);
829 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT: return BlendTest::QUAD_COUNT / static_cast<float>((1 << (numBits - 1)) - 1);
838 tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format)
841 using tcu::TextureFormat;
843 Vec4 threshold(0.01f);
847 case TextureFormat::UNORM_BYTE_44:
848 threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f);
851 case TextureFormat::UNORM_SHORT_565:
852 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f);
855 case TextureFormat::UNORM_SHORT_555:
856 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f);
859 case TextureFormat::UNORM_SHORT_4444:
860 threshold = Vec4(getNormChannelThreshold(format, 4));
863 case TextureFormat::UNORM_SHORT_5551:
864 threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f);
867 case TextureFormat::UNORM_INT_1010102_REV:
868 case TextureFormat::SNORM_INT_1010102_REV:
869 threshold = Vec4(getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), 0.34f);
872 case TextureFormat::UNORM_INT8:
873 case TextureFormat::SNORM_INT8:
874 threshold = Vec4(getNormChannelThreshold(format, 8));
877 case TextureFormat::UNORM_INT16:
878 case TextureFormat::SNORM_INT16:
879 threshold = Vec4(getNormChannelThreshold(format, 16));
882 case TextureFormat::UNORM_INT32:
883 case TextureFormat::SNORM_INT32:
884 threshold = Vec4(getNormChannelThreshold(format, 32));
887 case TextureFormat::HALF_FLOAT:
888 threshold = Vec4(0.005f);
891 case TextureFormat::FLOAT:
892 threshold = Vec4(0.00001f);
895 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
896 threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
899 case TextureFormat::UNSIGNED_INT_999_E5_REV:
900 threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
907 // Return value matching the channel order specified by the format
908 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
909 return threshold.swizzle(2, 1, 0, 3);
914 tcu::TestStatus BlendTestInstance::verifyImage (void)
916 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
917 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat(); // Undefined depth/stencil format
918 const ColorVertexShader vertexShader;
919 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
920 const rr::Program program (&vertexShader, &fragmentShader);
921 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
922 bool compareOk = false;
924 // Render reference image
926 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
928 const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];
931 rr::RenderState renderState (refRenderer.getViewportState());
932 renderState.fragOps.blendMode = rr::BLENDMODE_STANDARD;
933 renderState.fragOps.blendRGBState.srcFunc = mapVkBlendFactor(blendState.srcColorBlendFactor);
934 renderState.fragOps.blendRGBState.dstFunc = mapVkBlendFactor(blendState.dstColorBlendFactor);
935 renderState.fragOps.blendRGBState.equation = mapVkBlendOp(blendState.colorBlendOp);
936 renderState.fragOps.blendAState.srcFunc = mapVkBlendFactor(blendState.srcAlphaBlendFactor);
937 renderState.fragOps.blendAState.dstFunc = mapVkBlendFactor(blendState.dstAlphaBlendFactor);
938 renderState.fragOps.blendAState.equation = mapVkBlendOp(blendState.alphaBlendOp);
939 renderState.fragOps.blendColor = BlendTest::s_blendConst;
940 renderState.fragOps.colorMask = mapVkColorComponentFlags(BlendTest::s_colorWriteMasks[quadNdx]);
942 refRenderer.draw(renderState,
943 rr::PRIMITIVETYPE_TRIANGLES,
944 std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
945 m_vertices.begin() + (quadNdx + 1) * 6));
950 // Compare result with reference image
952 const DeviceInterface& vk = m_context.getDeviceInterface();
953 const VkDevice vkDevice = m_context.getDevice();
954 const VkQueue queue = m_context.getUniversalQueue();
955 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
956 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
957 de::UniquePtr<tcu::TextureLevel> result (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
958 const tcu::Vec4 threshold (getFormatThreshold(tcuColorFormat));
960 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
963 refRenderer.getAccess(),
966 tcu::COMPARE_LOG_RESULT);
970 return tcu::TestStatus::pass("Result image matches reference");
972 return tcu::TestStatus::fail("Image mismatch");
977 std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
979 const char* shortBlendFactorNames[] =
981 "z", // VK_BLEND_ZERO
983 "sc", // VK_BLEND_SRC_COLOR
984 "1msc", // VK_BLEND_ONE_MINUS_SRC_COLOR
985 "dc", // VK_BLEND_DEST_COLOR
986 "1mdc", // VK_BLEND_ONE_MINUS_DEST_COLOR
987 "sa", // VK_BLEND_SRC_ALPHA
988 "1msa", // VK_BLEND_ONE_MINUS_SRC_ALPHA
989 "da", // VK_BLEND_DEST_ALPHA
990 "1mda", // VK_BLEND_ONE_MINUS_DEST_ALPHA
991 "cc", // VK_BLEND_CONSTANT_COLOR
992 "1mcc", // VK_BLEND_ONE_MINUS_CONSTANT_COLOR
993 "ca", // VK_BLEND_CONSTANT_ALPHA
994 "1mca", // VK_BLEND_ONE_MINUS_CONSTANT_ALPHA
995 "sas" // VK_BLEND_SRC_ALPHA_SATURATE
998 const char* blendOpNames[] =
1000 "add", // VK_BLEND_OP_ADD
1001 "sub", // VK_BLEND_OP_SUBTRACT
1002 "rsub", // VK_BLEND_OP_REVERSE_SUBTRACT
1003 "min", // VK_BLEND_OP_MIN
1004 "max", // VK_BLEND_OP_MAX
1007 std::ostringstream shortName;
1009 shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp];
1010 shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp];
1012 return shortName.str();
1015 std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1017 std::ostringstream name;
1019 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1021 name << getBlendStateName(blendStates[quadNdx]);
1023 if (quadNdx < BlendTest::QUAD_COUNT - 1)
1030 std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1032 std::ostringstream description;
1034 description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n";
1036 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1037 description << blendStates[quadNdx] << "\n";
1039 return description.str();
1042 std::string getFormatCaseName (VkFormat format)
1044 const std::string fullName = getFormatName(format);
1046 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1048 return de::toLower(fullName.substr(10));
1051 tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx)
1053 const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT;
1055 // Formats that are dEQP-compatible, non-integer and uncompressed
1056 const VkFormat blendFormats[] =
1058 VK_FORMAT_R4G4_UNORM_PACK8,
1059 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1060 VK_FORMAT_R5G6B5_UNORM_PACK16,
1061 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1065 VK_FORMAT_R8G8_UNORM,
1066 VK_FORMAT_R8G8_SNORM,
1067 VK_FORMAT_R8G8_SRGB,
1068 VK_FORMAT_R8G8B8_UNORM,
1069 VK_FORMAT_R8G8B8_SNORM,
1070 VK_FORMAT_R8G8B8_SRGB,
1071 VK_FORMAT_R8G8B8A8_UNORM,
1072 VK_FORMAT_R8G8B8A8_SNORM,
1073 VK_FORMAT_R8G8B8A8_SRGB,
1074 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1075 VK_FORMAT_R16_UNORM,
1076 VK_FORMAT_R16_SNORM,
1077 VK_FORMAT_R16_SFLOAT,
1078 VK_FORMAT_R16G16_UNORM,
1079 VK_FORMAT_R16G16_SNORM,
1080 VK_FORMAT_R16G16_SFLOAT,
1081 VK_FORMAT_R16G16B16_UNORM,
1082 VK_FORMAT_R16G16B16_SNORM,
1083 VK_FORMAT_R16G16B16_SFLOAT,
1084 VK_FORMAT_R16G16B16A16_UNORM,
1085 VK_FORMAT_R16G16B16A16_SNORM,
1086 VK_FORMAT_R16G16B16A16_SFLOAT,
1087 VK_FORMAT_R32_SFLOAT,
1088 VK_FORMAT_R32G32_SFLOAT,
1089 VK_FORMAT_R32G32B32_SFLOAT,
1090 VK_FORMAT_R32G32B32A32_SFLOAT,
1091 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1092 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1093 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1094 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1097 de::MovePtr<tcu::TestCaseGroup> blendTests (new tcu::TestCaseGroup(testCtx, "blend", "Blend tests"));
1098 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));
1099 BlendStateUniqueRandomIterator blendStateItr (blendStatesPerFormat, 123);
1101 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
1103 const VkFormat format = blendFormats[formatNdx];
1104 de::MovePtr<tcu::TestCaseGroup> formatTest (new tcu::TestCaseGroup(testCtx,
1105 getFormatCaseName(format).c_str(),
1106 (std::string("Uses format ") + getFormatName(format)).c_str()));
1107 de::MovePtr<tcu::TestCaseGroup> blendStateTests;
1109 std::ostringstream blendStateDescription;
1110 blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst;
1111 blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str()));
1114 blendStateItr.reset();
1116 while (blendStateItr.hasNext())
1118 VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];
1120 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1122 quadBlendConfigs[quadNdx] = blendStateItr.next();
1123 quadBlendConfigs[quadNdx].colorWriteMask = BlendTest::s_colorWriteMasks[quadNdx];
1126 blendStateTests->addChild(new BlendTest(testCtx,
1127 getBlendStateSetName(quadBlendConfigs),
1128 getBlendStateSetDescription(quadBlendConfigs),
1132 formatTest->addChild(blendStateTests.release());
1133 formatTests->addChild(formatTest.release());
1135 blendTests->addChild(formatTests.release());
1137 return blendTests.release();