dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[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  * 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:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
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.
22  *
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.
30  *
31  *//*!
32  * \file
33  * \brief Blend Tests
34  *//*--------------------------------------------------------------------*/
35
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"
48 #include "vkRef.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"
56 #include <cstring>
57 #include <set>
58 #include <sstream>
59 #include <vector>
60
61 namespace vkt
62 {
63 namespace pipeline
64 {
65
66 using namespace vk;
67
68 namespace
69 {
70
71 bool isSupportedBlendFormat (const InstanceInterface& instanceInterface, VkPhysicalDevice device, VkFormat format)
72 {
73         VkFormatProperties formatProps;
74
75         instanceInterface.getPhysicalDeviceFormatProperties(device, format, &formatProps);
76
77         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) &&
78                    (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT);
79 }
80
81 class BlendStateUniqueRandomIterator : public UniqueRandomIterator<VkPipelineColorBlendAttachmentState>
82 {
83 public:
84                                                                                         BlendStateUniqueRandomIterator          (deUint32 numberOfCombinations, int seed);
85         virtual                                                                 ~BlendStateUniqueRandomIterator         (void) {}
86         VkPipelineColorBlendAttachmentState             getIndexedValue (deUint32 index);
87
88 private:
89         const static VkBlendFactor                              m_blendFactors[];
90         const static VkBlendOp                                  m_blendOps[];
91
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;
98
99         // Total number of cross-combinations of (srcBlendColor x destBlendColor x blendOpColor x srcBlendAlpha x destBlendAlpha x blendOpAlpha)
100         const static deUint32                                   m_totalBlendStates;
101 };
102
103 class BlendTest : public vkt::TestCase
104 {
105 public:
106         enum
107         {
108                 QUAD_COUNT = 4
109         };
110
111         const static VkColorComponentFlags      s_colorWriteMasks[QUAD_COUNT];
112         const static tcu::Vec4                          s_blendConst;
113
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;
122
123 private:
124         const VkFormat                                          m_colorFormat;
125         VkPipelineColorBlendAttachmentState     m_blendStates[QUAD_COUNT];
126 };
127
128 class BlendTestInstance : public vkt::TestInstance
129 {
130 public:
131                                                                                 BlendTestInstance               (Context& context, const VkFormat colorFormat, const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT]);
132         virtual                                                         ~BlendTestInstance              (void);
133         virtual tcu::TestStatus                         iterate                                 (void);
134
135 private:
136         static float                                            getNormChannelThreshold (const tcu::TextureFormat& format, int numBits);
137         static tcu::Vec4                                        getFormatThreshold              (const tcu::TextureFormat& format);
138         tcu::TestStatus                                         verifyImage                             (void);
139
140         VkPipelineColorBlendAttachmentState     m_blendStates[BlendTest::QUAD_COUNT];
141
142         const tcu::IVec2                                        m_renderSize;
143         const VkFormat                                          m_colorFormat;
144
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;
151
152         Move<VkShaderModule>                            m_vertexShaderModule;
153         Move<VkShaderModule>                            m_fragmentShaderModule;
154
155         Move<VkBuffer>                                          m_vertexBuffer;
156         std::vector<Vertex4RGBA>                        m_vertices;
157         de::MovePtr<Allocation>                         m_vertexBufferAlloc;
158
159         Move<VkPipelineLayout>                          m_pipelineLayout;
160         Move<VkPipeline>                                        m_graphicsPipelines[BlendTest::QUAD_COUNT];
161
162         Move<VkCommandPool>                                     m_cmdPool;
163         Move<VkCommandBuffer>                           m_cmdBuffer;
164
165         Move<VkFence>                                           m_fence;
166 };
167
168
169 // BlendStateUniqueRandomIterator
170
171 const VkBlendFactor BlendStateUniqueRandomIterator::m_blendFactors[] =
172 {
173         VK_BLEND_FACTOR_ZERO,
174         VK_BLEND_FACTOR_ONE,
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
188 };
189
190 const VkBlendOp BlendStateUniqueRandomIterator::m_blendOps[] =
191 {
192         VK_BLEND_OP_ADD,
193         VK_BLEND_OP_SUBTRACT,
194         VK_BLEND_OP_REVERSE_SUBTRACT,
195         VK_BLEND_OP_MIN,
196         VK_BLEND_OP_MAX
197 };
198
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;
205
206
207 BlendStateUniqueRandomIterator::BlendStateUniqueRandomIterator (deUint32 numberOfCombinations, int seed)
208         : UniqueRandomIterator<VkPipelineColorBlendAttachmentState>(numberOfCombinations, m_totalBlendStates, seed)
209 {
210 }
211
212 VkPipelineColorBlendAttachmentState BlendStateUniqueRandomIterator::getIndexedValue (deUint32 index)
213 {
214         const deUint32          blendOpAlphaIndex                       = index / (m_blendFactorsLength4 * m_blendOpsLength);
215         const deUint32          blendOpAlphaSeqIndex            = blendOpAlphaIndex * (m_blendFactorsLength4 * m_blendOpsLength);
216
217         const deUint32          destBlendAlphaIndex                     = (index - blendOpAlphaSeqIndex) / (m_blendFactorsLength3 * m_blendOpsLength);
218         const deUint32          destBlendAlphaSeqIndex          = destBlendAlphaIndex * (m_blendFactorsLength3 * m_blendOpsLength);
219
220         const deUint32          srcBlendAlphaIndex                      = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex) / (m_blendFactorsLength2 * m_blendOpsLength);
221         const deUint32          srcBlendAlphaSeqIndex           = srcBlendAlphaIndex * (m_blendFactorsLength2 * m_blendOpsLength);
222
223         const deUint32          blendOpColorIndex                       = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex) / m_blendFactorsLength2;
224         const deUint32          blendOpColorSeqIndex            = blendOpColorIndex * m_blendFactorsLength2;
225
226         const deUint32          destBlendColorIndex                     = (index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex) / m_blendFactorsLength;
227         const deUint32          destBlendColorSeqIndex          = destBlendColorIndex * m_blendFactorsLength;
228
229         const deUint32          srcBlendColorIndex                      = index - blendOpAlphaSeqIndex - destBlendAlphaSeqIndex - srcBlendAlphaSeqIndex - blendOpColorSeqIndex - destBlendColorSeqIndex;
230
231         const VkPipelineColorBlendAttachmentState blendAttachmentState =
232         {
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
242         };
243
244         return blendAttachmentState;
245 }
246
247
248 // BlendTest
249
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
254
255 const tcu::Vec4 BlendTest::s_blendConst = tcu::Vec4(0.1f, 0.2f, 0.3f, 0.4f);
256
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)
264 {
265         deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * QUAD_COUNT);
266 }
267
268 BlendTest::~BlendTest (void)
269 {
270 }
271
272 TestInstance* BlendTest::createInstance(Context& context) const
273 {
274         return new BlendTestInstance(context, m_colorFormat, m_blendStates);
275 }
276
277 void BlendTest::initPrograms (SourceCollections& sourceCollections) const
278 {
279         std::ostringstream fragmentSource;
280
281         sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
282                 "#version 310 es\n"
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"
286                 "void main (void)\n"
287                 "{\n"
288                 "       gl_Position = position;\n"
289                 "       vtxColor = color;\n"
290                 "}\n");
291
292         fragmentSource << "#version 310 es\n"
293                 "layout(location = 0) in highp vec4 vtxColor;\n"
294                 "layout(location = 0) out highp vec4 fragColor;\n"
295                 "void main (void)\n"
296                 "{\n"
297                 "       fragColor = vtxColor;\n"
298                 "}\n";
299
300         sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
301 }
302
303
304 // BlendTestInstance
305
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)
312 {
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()));
317
318         // Copy depth operators
319         deMemcpy(m_blendStates, blendStates, sizeof(VkPipelineColorBlendAttachmentState) * BlendTest::QUAD_COUNT);
320
321         // Create color image
322         {
323                 if (!isSupportedBlendFormat(context.getInstanceInterface(), context.getPhysicalDevice(), m_colorFormat))
324                         throw tcu::NotSupportedError(std::string("Unsupported color blending format: ") + getFormatName(m_colorFormat));
325
326                 const VkImageCreateInfo colorImageParams =
327                 {
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;
343                 };
344
345                 m_colorImageCreateInfo  = colorImageParams;
346                 m_colorImage                    = createImage(vk, vkDevice, &m_colorImageCreateInfo);
347
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()));
351         }
352
353         // Create color attachment view
354         {
355                 const VkImageViewCreateInfo colorAttachmentViewParams =
356                 {
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;
365                 };
366
367                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
368         }
369
370         // Create render pass
371         {
372                 const VkAttachmentDescription colorAttachmentDescription =
373                 {
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;
383                 };
384
385                 const VkAttachmentReference colorAttachmentReference =
386                 {
387                         0u,                                                                                                     // deUint32                     attachment;
388                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
389                 };
390
391                 const VkSubpassDescription subpassDescription =
392                 {
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;
403                 };
404
405                 const VkRenderPassCreateInfo renderPassParams =
406                 {
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;
416                 };
417
418                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
419         }
420
421         // Create framebuffer
422         {
423                 const VkFramebufferCreateInfo framebufferParams =
424                 {
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;
434                 };
435
436                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
437         }
438
439         // Create pipeline layout
440         {
441                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
442                 {
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;
450                 };
451
452                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
453         }
454
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);
457
458         // Create pipeline
459         {
460                 const VkPipelineShaderStageCreateInfo shaderStages[2] =
461                 {
462                         {
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;
470                         },
471                         {
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;
479                         }
480                 };
481
482                 const VkVertexInputBindingDescription vertexInputBindingDescription =
483                 {
484                         0u,                                                                     // deUint32                                     binding;
485                         sizeof(Vertex4RGBA),                            // deUint32                                     strideInBytes;
486                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputStepRate        inputRate;
487                 };
488
489                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
490                 {
491                         {
492                                 0u,                                                             // deUint32     location;
493                                 0u,                                                             // deUint32     binding;
494                                 VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat     format;
495                                 0u                                                              // deUint32     offset;
496                         },
497                         {
498                                 1u,                                                             // deUint32     location;
499                                 0u,                                                             // deUint32     binding;
500                                 VK_FORMAT_R32G32B32A32_SFLOAT,  // VkFormat     format;
501                                 (deUint32)(sizeof(float) * 4),  // deUint32     offset;
502                         }
503                 };
504
505                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
506                 {
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;
514                 };
515
516                 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
517                 {
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;
523                 };
524
525                 const VkViewport viewport =
526                 {
527                         0.0f,                                           // float        x;
528                         0.0f,                                           // float        y;
529                         (float)m_renderSize.x(),        // float        width;
530                         (float)m_renderSize.y(),        // float        height;
531                         0.0f,                                           // float        minDepth;
532                         1.0f                                            // float        maxDepth;
533                 };
534
535                 const VkRect2D scissor = { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } };
536
537                 const VkPipelineViewportStateCreateInfo viewportStateParams =
538                 {
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;
546                 };
547
548                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
549                 {
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;
563                 };
564
565                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
566                 {
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;
576                 };
577
578                 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
579                 {
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;
589                         {
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;
597                         },
598                         // VkStencilOpState     back;
599                         {
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;
607                         },
608                         -1.0f,                                                                                                          // float                        minDepthBounds;
609                         +1.0f                                                                                                           // float                        maxDepthBounds;
610                 };
611
612                 // The color blend attachment will be set up before creating the graphics pipeline.
613                 VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
614                 {
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()
627                         }
628                 };
629
630                 const VkPipelineDynamicStateCreateInfo dynamicStateParams =
631                 {
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;
637                 };
638
639                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
640                 {
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;
660                 };
661
662                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
663                 {
664                         colorBlendStateParams.attachmentCount   = 1u;
665                         colorBlendStateParams.pAttachments              = &m_blendStates[quadNdx];
666                         m_graphicsPipelines[quadNdx]                    = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
667                 }
668         }
669
670         // Create vertex buffer
671         {
672                 const VkBufferCreateInfo vertexBufferParams =
673                 {
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;
682                 };
683
684                 m_vertices                      = createOverlappingQuads();
685                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
686                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
687
688                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
689
690                 // Adjust vertex colors
691                 if (!isFloatFormat(m_colorFormat))
692                 {
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;
696                 }
697
698                 // Upload vertex data
699                 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
700
701                 const VkMappedMemoryRange flushRange =
702                 {
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;
708                 };
709
710                 vk.flushMappedMemoryRanges(vkDevice, 1, &flushRange);
711         }
712
713         // Create command pool
714         {
715                 const VkCommandPoolCreateInfo cmdPoolParams =
716                 {
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;
721                 };
722
723                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
724         }
725
726         // Create command buffer
727         {
728                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
729                 {
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;
735                 };
736
737                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
738                 {
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;
748                 };
749
750                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
751
752                 const VkRenderPassBeginInfo renderPassBeginInfo =
753                 {
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;
761                 };
762
763                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
764
765                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
766                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
767
768                 const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
769
770                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
771                 {
772                         VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
773
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);
777                 }
778
779                 vk.cmdEndRenderPass(*m_cmdBuffer);
780                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
781         }
782
783         // Create fence
784         {
785                 const VkFenceCreateInfo fenceParams =
786                 {
787                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
788                         DE_NULL,                                                                // const void*                  pNext;
789                         0u                                                                              // VkFenceCreateFlags   flags;
790                 };
791
792                 m_fence = createFence(vk, vkDevice, &fenceParams);
793         }
794 }
795
796 BlendTestInstance::~BlendTestInstance (void)
797 {
798 }
799
800 tcu::TestStatus BlendTestInstance::iterate (void)
801 {
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      =
806         {
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;
815         };
816
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 */));
820
821         return verifyImage();
822 }
823
824 float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
825 {
826         switch (tcu::getTextureChannelClass(format.type))
827         {
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);
830                 default:
831                         break;
832         }
833
834         DE_ASSERT(false);
835         return 0.0f;
836 }
837
838 tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format)
839 {
840         using tcu::Vec4;
841         using tcu::TextureFormat;
842
843         Vec4 threshold(0.01f);
844
845         switch (format.type)
846         {
847                 case TextureFormat::UNORM_BYTE_44:
848                         threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f);
849                         break;
850
851                 case TextureFormat::UNORM_SHORT_565:
852                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f);
853                         break;
854
855                 case TextureFormat::UNORM_SHORT_555:
856                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f);
857                         break;
858
859                 case TextureFormat::UNORM_SHORT_4444:
860                         threshold = Vec4(getNormChannelThreshold(format, 4));
861                         break;
862
863                 case TextureFormat::UNORM_SHORT_5551:
864                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f);
865                         break;
866
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);
870                         break;
871
872                 case TextureFormat::UNORM_INT8:
873                 case TextureFormat::SNORM_INT8:
874                         threshold = Vec4(getNormChannelThreshold(format, 8));
875                         break;
876
877                 case TextureFormat::UNORM_INT16:
878                 case TextureFormat::SNORM_INT16:
879                         threshold = Vec4(getNormChannelThreshold(format, 16));
880                         break;
881
882                 case TextureFormat::UNORM_INT32:
883                 case TextureFormat::SNORM_INT32:
884                         threshold = Vec4(getNormChannelThreshold(format, 32));
885                         break;
886
887                 case TextureFormat::HALF_FLOAT:
888                         threshold = Vec4(0.005f);
889                         break;
890
891                 case TextureFormat::FLOAT:
892                         threshold = Vec4(0.00001f);
893                         break;
894
895                 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
896                         threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
897                         break;
898
899                 case TextureFormat::UNSIGNED_INT_999_E5_REV:
900                         threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
901                         break;
902
903                 default:
904                         DE_ASSERT(false);
905         }
906
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);
910         else
911                 return threshold;
912 }
913
914 tcu::TestStatus BlendTestInstance::verifyImage (void)
915 {
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;
923
924         // Render reference image
925         {
926                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
927                 {
928                         const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];
929
930                         // Set blend state
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]);
941
942                         refRenderer.draw(renderState,
943                                                          rr::PRIMITIVETYPE_TRIANGLES,
944                                                          std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
945                                                                                                           m_vertices.begin() + (quadNdx + 1) * 6));
946                 }
947         }
948
949
950         // Compare result with reference image
951         {
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));
959
960                 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
961                                                                                            "FloatImageCompare",
962                                                                                            "Image comparison",
963                                                                                            refRenderer.getAccess(),
964                                                                                            result->getAccess(),
965                                                                                            threshold,
966                                                                                            tcu::COMPARE_LOG_RESULT);
967         }
968
969         if (compareOk)
970                 return tcu::TestStatus::pass("Result image matches reference");
971         else
972                 return tcu::TestStatus::fail("Image mismatch");
973 }
974
975 } // anonymous
976
977 std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
978 {
979         const char* shortBlendFactorNames[] =
980         {
981                 "z",            // VK_BLEND_ZERO
982                 "o",            // VK_BLEND_ONE
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
996         };
997
998         const char* blendOpNames[] =
999         {
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
1005         };
1006
1007         std::ostringstream shortName;
1008
1009         shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp];
1010         shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp];
1011
1012         return shortName.str();
1013 }
1014
1015 std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1016 {
1017         std::ostringstream name;
1018
1019         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1020         {
1021                 name << getBlendStateName(blendStates[quadNdx]);
1022
1023                 if (quadNdx < BlendTest::QUAD_COUNT - 1)
1024                         name << "-";
1025         }
1026
1027         return name.str();
1028 }
1029
1030 std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1031 {
1032         std::ostringstream description;
1033
1034         description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n";
1035
1036         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1037                 description << blendStates[quadNdx] << "\n";
1038
1039         return description.str();
1040 }
1041
1042 std::string getFormatCaseName (VkFormat format)
1043 {
1044         const std::string fullName = getFormatName(format);
1045
1046         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1047
1048         return de::toLower(fullName.substr(10));
1049 }
1050
1051 tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx)
1052 {
1053         const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT;
1054
1055         // Formats that are dEQP-compatible, non-integer and uncompressed
1056         const VkFormat blendFormats[] =
1057         {
1058                 VK_FORMAT_R4G4_UNORM_PACK8,
1059                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1060                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1061                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1062                 VK_FORMAT_R8_UNORM,
1063                 VK_FORMAT_R8_SNORM,
1064                 VK_FORMAT_R8_SRGB,
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,
1095         };
1096
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);
1100
1101         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
1102         {
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;
1108                 {
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()));
1112                 }
1113
1114                 blendStateItr.reset();
1115
1116                 while (blendStateItr.hasNext())
1117                 {
1118                         VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];
1119
1120                         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1121                         {
1122                                 quadBlendConfigs[quadNdx]                                       = blendStateItr.next();
1123                                 quadBlendConfigs[quadNdx].colorWriteMask        = BlendTest::s_colorWriteMasks[quadNdx];
1124                         }
1125
1126                         blendStateTests->addChild(new BlendTest(testCtx,
1127                                                                                                         getBlendStateSetName(quadBlendConfigs),
1128                                                                                                         getBlendStateSetDescription(quadBlendConfigs),
1129                                                                                                         format,
1130                                                                                                         quadBlendConfigs));
1131                 }
1132                 formatTest->addChild(blendStateTests.release());
1133                 formatTests->addChild(formatTest.release());
1134         }
1135         blendTests->addChild(formatTests.release());
1136
1137         return blendTests.release();
1138 }
1139
1140 } // pipeline
1141 } // vkt