Fix issues in pipeline.timestamp.transfer_tests
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineBlendTests.cpp
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
50 namespace vkt
51 {
52 namespace pipeline
53 {
54
55 using namespace vk;
56
57 namespace
58 {
59
60 bool 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
70 class BlendStateUniqueRandomIterator : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState>
71 {
72 public:
73                                                                                         BlendStateUniqueRandomIterator          (deUint32 numberOfCombinations, int seed);
74         virtual                                                                 ~BlendStateUniqueRandomIterator         (void) {}
75         VkPipelineColorBlendAttachmentState             getIndexedValue (deUint32 index);
76
77 private:
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
92 class BlendTest : public vkt::TestCase
93 {
94 public:
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
112 private:
113         const VkFormat                                          m_colorFormat;
114         VkPipelineColorBlendAttachmentState     m_blendStates[QUAD_COUNT];
115 };
116
117 class BlendTestInstance : public vkt::TestInstance
118 {
119 public:
120                                                                                 BlendTestInstance               (Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]);
121         virtual                                                         ~BlendTestInstance              (void);
122         virtual tcu::TestStatus                         iterate                                 (void);
123
124 private:
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
160 const 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
179 const 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
188 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength             = DE_LENGTH_OF_ARRAY(m_blendFactors);
189 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength2    = m_blendFactorsLength * m_blendFactorsLength;
190 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength3    = m_blendFactorsLength2 * m_blendFactorsLength;
191 const deUint32 BlendStateUniqueRandomIterator::m_blendFactorsLength4    = m_blendFactorsLength3 * m_blendFactorsLength;
192 const deUint32 BlendStateUniqueRandomIterator::m_blendOpsLength                 = DE_LENGTH_OF_ARRAY(m_blendOps);
193 const deUint32 BlendStateUniqueRandomIterator::m_totalBlendStates               = m_blendFactorsLength4 * m_blendOpsLength * m_blendOpsLength;
194
195
196 BlendStateUniqueRandomIterator::BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed)
197         : UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed)
198 {
199 }
200
201 VkPipelineColorBlendAttachmentState 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
239 const 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
244 const tcu::Vec4 BlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);
245
246 BlendTest::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
257 BlendTest::~BlendTest (void)
258 {
259 }
260
261 TestInstance* BlendTest::createInstance(Context& context) const
262 {
263         return new BlendTestInstance(context, m_colorFormat, m_blendStates);
264 }
265
266 void 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
295 BlendTestInstance::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         {
695                 const VkCommandPoolCreateInfo cmdPoolParams =
696                 {
697                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                      sType;
698                         DE_NULL,                                                                                // const void*                          pNext;
699                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags     flags;
700                         queueFamilyIndex                                                                // deUint32                                     queueFamilyIndex;
701                 };
702
703                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
704         }
705
706         // Create command buffer
707         {
708                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
709                 {
710                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
711                         DE_NULL,                                                                                // const void*                          pNext;
712                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
713                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel         level;
714                         1u,                                                                                             // deUint32                             bufferCount;
715                 };
716
717                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
718                 {
719                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
720                         DE_NULL,                                                                                // const void*                                          pNext;
721                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
722                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
723                 };
724
725                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
726
727                 const VkRenderPassBeginInfo renderPassBeginInfo =
728                 {
729                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
730                         DE_NULL,                                                                                                // const void*                  pNext;
731                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
732                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
733                         { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
734                         1,                                                                                                              // deUint32                             clearValueCount;
735                         &attachmentClearValue                                                                   // const VkClearValue*  pClearValues;
736                 };
737
738                 // Color image layout transition
739                 const VkImageMemoryBarrier imageLayoutBarrier =
740                 {
741                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType            sType;
742                         DE_NULL,                                                                                                                                // const void*                pNext;
743                         (VkAccessFlags)0,                                                                                                               // VkAccessFlags              srcAccessMask;
744                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                   // VkAccessFlags              dstAccessMask;
745                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout              oldLayout;
746                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                               // VkImageLayout              newLayout;
747                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   srcQueueFamilyIndex;
748                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   dstQueueFamilyIndex;
749                         *m_colorImage,                                                                                                                  // VkImage                    image;
750                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }                                                   // VkImageSubresourceRange    subresourceRange;
751                 };
752
753                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
754
755                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
756
757                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
758                         0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier);
759
760                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
761
762                 const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
763
764                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
765                 {
766                         VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
767
768                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
769                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
770                         vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / BlendTest::QUAD_COUNT), 1, 0, 0);
771                 }
772
773                 vk.cmdEndRenderPass(*m_cmdBuffer);
774                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
775         }
776
777         // Create fence
778         {
779                 const VkFenceCreateInfo fenceParams =
780                 {
781                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
782                         DE_NULL,                                                                // const void*                  pNext;
783                         0u                                                                              // VkFenceCreateFlags   flags;
784                 };
785
786                 m_fence = createFence(vk, vkDevice, &fenceParams);
787         }
788 }
789
790 BlendTestInstance::~BlendTestInstance (void)
791 {
792 }
793
794 tcu::TestStatus BlendTestInstance::iterate (void)
795 {
796         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
797         const VkDevice                          vkDevice        = m_context.getDevice();
798         const VkQueue                           queue           = m_context.getUniversalQueue();
799         const VkSubmitInfo                      submitInfo      =
800         {
801                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
802                 DE_NULL,                                                // const void*                          pNext;
803                 0u,                                                             // deUint32                                     waitSemaphoreCount;
804                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
805                 (const VkPipelineStageFlags*)DE_NULL,
806                 1u,                                                             // deUint32                                     commandBufferCount;
807                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
808                 0u,                                                             // deUint32                                     signalSemaphoreCount;
809                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
810         };
811
812         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
813         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
814         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
815
816         return verifyImage();
817 }
818
819 float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
820 {
821         switch (tcu::getTextureChannelClass(format.type))
822         {
823                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:     return BlendTest::QUAD_COUNT / static_cast<float>((1 << numBits) - 1);
824                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:       return BlendTest::QUAD_COUNT / static_cast<float>((1 << (numBits - 1)) - 1);
825                 default:
826                         break;
827         }
828
829         DE_ASSERT(false);
830         return 0.0f;
831 }
832
833 tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format)
834 {
835         using tcu::Vec4;
836         using tcu::TextureFormat;
837
838         Vec4 threshold(0.01f);
839
840         switch (format.type)
841         {
842                 case TextureFormat::UNORM_BYTE_44:
843                         threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f);
844                         break;
845
846                 case TextureFormat::UNORM_SHORT_565:
847                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f);
848                         break;
849
850                 case TextureFormat::UNORM_SHORT_555:
851                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f);
852                         break;
853
854                 case TextureFormat::UNORM_SHORT_4444:
855                         threshold = Vec4(getNormChannelThreshold(format, 4));
856                         break;
857
858                 case TextureFormat::UNORM_SHORT_5551:
859                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f);
860                         break;
861
862                 case TextureFormat::UNORM_INT_1010102_REV:
863                 case TextureFormat::SNORM_INT_1010102_REV:
864                         threshold = Vec4(getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), 0.34f);
865                         break;
866
867                 case TextureFormat::UNORM_INT8:
868                 case TextureFormat::SNORM_INT8:
869                         threshold = Vec4(getNormChannelThreshold(format, 8));
870                         break;
871
872                 case TextureFormat::UNORM_INT16:
873                 case TextureFormat::SNORM_INT16:
874                         threshold = Vec4(getNormChannelThreshold(format, 16));
875                         break;
876
877                 case TextureFormat::UNORM_INT32:
878                 case TextureFormat::SNORM_INT32:
879                         threshold = Vec4(getNormChannelThreshold(format, 32));
880                         break;
881
882                 case TextureFormat::HALF_FLOAT:
883                         threshold = Vec4(0.005f);
884                         break;
885
886                 case TextureFormat::FLOAT:
887                         threshold = Vec4(0.00001f);
888                         break;
889
890                 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
891                         threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
892                         break;
893
894                 case TextureFormat::UNSIGNED_INT_999_E5_REV:
895                         threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
896                         break;
897
898                 default:
899                         DE_ASSERT(false);
900         }
901
902         // Return value matching the channel order specified by the format
903         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
904                 return threshold.swizzle(2, 1, 0, 3);
905         else
906                 return threshold;
907 }
908
909 tcu::TestStatus BlendTestInstance::verifyImage (void)
910 {
911         const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
912         const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat(); // Undefined depth/stencil format
913         const ColorVertexShader         vertexShader;
914         const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
915         const rr::Program                       program                 (&vertexShader, &fragmentShader);
916         ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
917         bool                                            compareOk               = false;
918
919         // Render reference image
920         {
921                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
922                 {
923                         const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];
924
925                         // Set blend state
926                         rr::RenderState renderState                                     (refRenderer.getViewportState());
927                         renderState.fragOps.blendMode                           = rr::BLENDMODE_STANDARD;
928                         renderState.fragOps.blendRGBState.srcFunc       = mapVkBlendFactor(blendState.srcColorBlendFactor);
929                         renderState.fragOps.blendRGBState.dstFunc       = mapVkBlendFactor(blendState.dstColorBlendFactor);
930                         renderState.fragOps.blendRGBState.equation      = mapVkBlendOp(blendState.colorBlendOp);
931                         renderState.fragOps.blendAState.srcFunc         = mapVkBlendFactor(blendState.srcAlphaBlendFactor);
932                         renderState.fragOps.blendAState.dstFunc         = mapVkBlendFactor(blendState.dstAlphaBlendFactor);
933                         renderState.fragOps.blendAState.equation        = mapVkBlendOp(blendState.alphaBlendOp);
934                         renderState.fragOps.blendColor                          = BlendTest::s_blendConst;
935                         renderState.fragOps.colorMask                           = mapVkColorComponentFlags(BlendTest::s_colorWriteMasks[quadNdx]);
936
937                         refRenderer.draw(renderState,
938                                                          rr::PRIMITIVETYPE_TRIANGLES,
939                                                          std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
940                                                                                                           m_vertices.begin() + (quadNdx + 1) * 6));
941                 }
942         }
943
944
945         // Compare result with reference image
946         {
947                 const DeviceInterface&                          vk                                                      = m_context.getDeviceInterface();
948                 const VkDevice                                          vkDevice                                        = m_context.getDevice();
949                 const VkQueue                                           queue                                           = m_context.getUniversalQueue();
950                 const deUint32                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
951                 SimpleAllocator                                         allocator                                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
952                 de::UniquePtr<tcu::TextureLevel>        result                                          (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
953                 const tcu::Vec4                                         threshold                                       (getFormatThreshold(tcuColorFormat));
954
955                 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
956                                                                                            "FloatImageCompare",
957                                                                                            "Image comparison",
958                                                                                            refRenderer.getAccess(),
959                                                                                            result->getAccess(),
960                                                                                            threshold,
961                                                                                            tcu::COMPARE_LOG_RESULT);
962         }
963
964         if (compareOk)
965                 return tcu::TestStatus::pass("Result image matches reference");
966         else
967                 return tcu::TestStatus::fail("Image mismatch");
968 }
969
970 } // anonymous
971
972 std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
973 {
974         const char* shortBlendFactorNames[] =
975         {
976                 "z",            // VK_BLEND_ZERO
977                 "o",            // VK_BLEND_ONE
978                 "sc",           // VK_BLEND_SRC_COLOR
979                 "1msc",         // VK_BLEND_ONE_MINUS_SRC_COLOR
980                 "dc",           // VK_BLEND_DEST_COLOR
981                 "1mdc",         // VK_BLEND_ONE_MINUS_DEST_COLOR
982                 "sa",           // VK_BLEND_SRC_ALPHA
983                 "1msa",         // VK_BLEND_ONE_MINUS_SRC_ALPHA
984                 "da",           // VK_BLEND_DEST_ALPHA
985                 "1mda",         // VK_BLEND_ONE_MINUS_DEST_ALPHA
986                 "cc",           // VK_BLEND_CONSTANT_COLOR
987                 "1mcc",         // VK_BLEND_ONE_MINUS_CONSTANT_COLOR
988                 "ca",           // VK_BLEND_CONSTANT_ALPHA
989                 "1mca",         // VK_BLEND_ONE_MINUS_CONSTANT_ALPHA
990                 "sas"           // VK_BLEND_SRC_ALPHA_SATURATE
991         };
992
993         const char* blendOpNames[] =
994         {
995                 "add",          // VK_BLEND_OP_ADD
996                 "sub",          // VK_BLEND_OP_SUBTRACT
997                 "rsub",         // VK_BLEND_OP_REVERSE_SUBTRACT
998                 "min",          // VK_BLEND_OP_MIN
999                 "max",          // VK_BLEND_OP_MAX
1000         };
1001
1002         std::ostringstream shortName;
1003
1004         shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp];
1005         shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp];
1006
1007         return shortName.str();
1008 }
1009
1010 std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1011 {
1012         std::ostringstream name;
1013
1014         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1015         {
1016                 name << getBlendStateName(blendStates[quadNdx]);
1017
1018                 if (quadNdx < BlendTest::QUAD_COUNT - 1)
1019                         name << "-";
1020         }
1021
1022         return name.str();
1023 }
1024
1025 std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1026 {
1027         std::ostringstream description;
1028
1029         description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n";
1030
1031         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1032                 description << blendStates[quadNdx] << "\n";
1033
1034         return description.str();
1035 }
1036
1037 std::string getFormatCaseName (VkFormat format)
1038 {
1039         const std::string fullName = getFormatName(format);
1040
1041         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1042
1043         return de::toLower(fullName.substr(10));
1044 }
1045
1046 tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx)
1047 {
1048         const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT;
1049
1050         // Formats that are dEQP-compatible, non-integer and uncompressed
1051         const VkFormat blendFormats[] =
1052         {
1053                 VK_FORMAT_R4G4_UNORM_PACK8,
1054                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1055                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1056                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1057                 VK_FORMAT_R8_UNORM,
1058                 VK_FORMAT_R8_SNORM,
1059                 VK_FORMAT_R8_SRGB,
1060                 VK_FORMAT_R8G8_UNORM,
1061                 VK_FORMAT_R8G8_SNORM,
1062                 VK_FORMAT_R8G8_SRGB,
1063                 VK_FORMAT_R8G8B8_UNORM,
1064                 VK_FORMAT_R8G8B8_SNORM,
1065                 VK_FORMAT_R8G8B8_SRGB,
1066                 VK_FORMAT_R8G8B8A8_UNORM,
1067                 VK_FORMAT_R8G8B8A8_SNORM,
1068                 VK_FORMAT_R8G8B8A8_SRGB,
1069                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1070                 VK_FORMAT_R16_UNORM,
1071                 VK_FORMAT_R16_SNORM,
1072                 VK_FORMAT_R16_SFLOAT,
1073                 VK_FORMAT_R16G16_UNORM,
1074                 VK_FORMAT_R16G16_SNORM,
1075                 VK_FORMAT_R16G16_SFLOAT,
1076                 VK_FORMAT_R16G16B16_UNORM,
1077                 VK_FORMAT_R16G16B16_SNORM,
1078                 VK_FORMAT_R16G16B16_SFLOAT,
1079                 VK_FORMAT_R16G16B16A16_UNORM,
1080                 VK_FORMAT_R16G16B16A16_SNORM,
1081                 VK_FORMAT_R16G16B16A16_SFLOAT,
1082                 VK_FORMAT_R32_SFLOAT,
1083                 VK_FORMAT_R32G32_SFLOAT,
1084                 VK_FORMAT_R32G32B32_SFLOAT,
1085                 VK_FORMAT_R32G32B32A32_SFLOAT,
1086                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1087                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1088                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1089                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1090         };
1091
1092         de::MovePtr<tcu::TestCaseGroup>         blendTests              (new tcu::TestCaseGroup(testCtx, "blend", "Blend tests"));
1093         de::MovePtr<tcu::TestCaseGroup>         formatTests             (new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));
1094         BlendStateUniqueRandomIterator          blendStateItr   (blendStatesPerFormat, 123);
1095
1096         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
1097         {
1098                 const VkFormat                                  format                  = blendFormats[formatNdx];
1099                 de::MovePtr<tcu::TestCaseGroup> formatTest              (new tcu::TestCaseGroup(testCtx,
1100                                                                                                                                                                 getFormatCaseName(format).c_str(),
1101                                                                                                                                                                 (std::string("Uses format ") + getFormatName(format)).c_str()));
1102                 de::MovePtr<tcu::TestCaseGroup> blendStateTests;
1103                 {
1104                         std::ostringstream blendStateDescription;
1105                         blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst;
1106                         blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str()));
1107                 }
1108
1109                 blendStateItr.reset();
1110
1111                 while (blendStateItr.hasNext())
1112                 {
1113                         VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];
1114
1115                         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1116                         {
1117                                 quadBlendConfigs[quadNdx]                                       = blendStateItr.next();
1118                                 quadBlendConfigs[quadNdx].colorWriteMask        = BlendTest::s_colorWriteMasks[quadNdx];
1119                         }
1120
1121                         blendStateTests->addChild(new BlendTest(testCtx,
1122                                                                                                         getBlendStateSetName(quadBlendConfigs),
1123                                                                                                         getBlendStateSetDescription(quadBlendConfigs),
1124                                                                                                         format,
1125                                                                                                         quadBlendConfigs));
1126                 }
1127                 formatTest->addChild(blendStateTests.release());
1128                 formatTests->addChild(formatTest.release());
1129         }
1130         blendTests->addChild(formatTests.release());
1131
1132         return blendTests.release();
1133 }
1134
1135 } // pipeline
1136 } // vkt