Merge "Remove EGL gles1.rgb565_window from mustpass" into oc-dev am: 840e33e440
[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         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
695
696         // Create command buffer
697         {
698                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
699                 {
700                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
701                         DE_NULL,                                                                                // const void*                                          pNext;
702                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
703                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
704                 };
705
706                 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
707
708                 const VkRenderPassBeginInfo renderPassBeginInfo =
709                 {
710                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
711                         DE_NULL,                                                                                                // const void*                  pNext;
712                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
713                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
714                         { { 0, 0 }, { m_renderSize.x(), m_renderSize.y() } },   // VkRect2D                             renderArea;
715                         1,                                                                                                              // deUint32                             clearValueCount;
716                         &attachmentClearValue                                                                   // const VkClearValue*  pClearValues;
717                 };
718
719                 // Color image layout transition
720                 const VkImageMemoryBarrier imageLayoutBarrier =
721                 {
722                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                                                                 // VkStructureType            sType;
723                         DE_NULL,                                                                                                                                // const void*                pNext;
724                         (VkAccessFlags)0,                                                                                                               // VkAccessFlags              srcAccessMask;
725                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                                                                   // VkAccessFlags              dstAccessMask;
726                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                              // VkImageLayout              oldLayout;
727                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                                                               // VkImageLayout              newLayout;
728                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   srcQueueFamilyIndex;
729                         VK_QUEUE_FAMILY_IGNORED,                                                                                                // uint32_t                   dstQueueFamilyIndex;
730                         *m_colorImage,                                                                                                                  // VkImage                    image;
731                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }                                                   // VkImageSubresourceRange    subresourceRange;
732                 };
733
734                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
735
736                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
737
738                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
739                         0u, DE_NULL, 0u, DE_NULL, 1u, &imageLayoutBarrier);
740
741                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
742
743                 const VkDeviceSize quadOffset = (m_vertices.size() / BlendTest::QUAD_COUNT) * sizeof(Vertex4RGBA);
744
745                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
746                 {
747                         VkDeviceSize vertexBufferOffset = quadOffset * quadNdx;
748
749                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines[quadNdx]);
750                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
751                         vk.cmdDraw(*m_cmdBuffer, (deUint32)(m_vertices.size() / BlendTest::QUAD_COUNT), 1, 0, 0);
752                 }
753
754                 vk.cmdEndRenderPass(*m_cmdBuffer);
755                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
756         }
757
758         // Create fence
759         m_fence = createFence(vk, vkDevice);
760 }
761
762 BlendTestInstance::~BlendTestInstance (void)
763 {
764 }
765
766 tcu::TestStatus BlendTestInstance::iterate (void)
767 {
768         const DeviceInterface&          vk                      = m_context.getDeviceInterface();
769         const VkDevice                          vkDevice        = m_context.getDevice();
770         const VkQueue                           queue           = m_context.getUniversalQueue();
771         const VkSubmitInfo                      submitInfo      =
772         {
773                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
774                 DE_NULL,                                                // const void*                          pNext;
775                 0u,                                                             // deUint32                                     waitSemaphoreCount;
776                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
777                 (const VkPipelineStageFlags*)DE_NULL,
778                 1u,                                                             // deUint32                                     commandBufferCount;
779                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
780                 0u,                                                             // deUint32                                     signalSemaphoreCount;
781                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
782         };
783
784         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
785         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
786         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
787
788         return verifyImage();
789 }
790
791 float BlendTestInstance::getNormChannelThreshold (const tcu::TextureFormat& format, int numBits)
792 {
793         switch (tcu::getTextureChannelClass(format.type))
794         {
795                 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:     return BlendTest::QUAD_COUNT / static_cast<float>((1 << numBits) - 1);
796                 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:       return BlendTest::QUAD_COUNT / static_cast<float>((1 << (numBits - 1)) - 1);
797                 default:
798                         break;
799         }
800
801         DE_ASSERT(false);
802         return 0.0f;
803 }
804
805 tcu::Vec4 BlendTestInstance::getFormatThreshold (const tcu::TextureFormat& format)
806 {
807         using tcu::Vec4;
808         using tcu::TextureFormat;
809
810         Vec4 threshold(0.01f);
811
812         switch (format.type)
813         {
814                 case TextureFormat::UNORM_BYTE_44:
815                         threshold = Vec4(getNormChannelThreshold(format, 4), getNormChannelThreshold(format, 4), 1.0f, 1.0f);
816                         break;
817
818                 case TextureFormat::UNORM_SHORT_565:
819                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 6), getNormChannelThreshold(format, 5), 1.0f);
820                         break;
821
822                 case TextureFormat::UNORM_SHORT_555:
823                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 1.0f);
824                         break;
825
826                 case TextureFormat::UNORM_SHORT_4444:
827                         threshold = Vec4(getNormChannelThreshold(format, 4));
828                         break;
829
830                 case TextureFormat::UNORM_SHORT_5551:
831                         threshold = Vec4(getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), getNormChannelThreshold(format, 5), 0.1f);
832                         break;
833
834                 case TextureFormat::UNORM_INT_1010102_REV:
835                 case TextureFormat::SNORM_INT_1010102_REV:
836                         threshold = Vec4(getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), getNormChannelThreshold(format, 10), 0.34f);
837                         break;
838
839                 case TextureFormat::UNORM_INT8:
840                 case TextureFormat::SNORM_INT8:
841                         threshold = Vec4(getNormChannelThreshold(format, 8));
842                         break;
843
844                 case TextureFormat::UNORM_INT16:
845                 case TextureFormat::SNORM_INT16:
846                         threshold = Vec4(getNormChannelThreshold(format, 16));
847                         break;
848
849                 case TextureFormat::UNORM_INT32:
850                 case TextureFormat::SNORM_INT32:
851                         threshold = Vec4(getNormChannelThreshold(format, 32));
852                         break;
853
854                 case TextureFormat::HALF_FLOAT:
855                         threshold = Vec4(0.005f);
856                         break;
857
858                 case TextureFormat::FLOAT:
859                         threshold = Vec4(0.00001f);
860                         break;
861
862                 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
863                         threshold = Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
864                         break;
865
866                 case TextureFormat::UNSIGNED_INT_999_E5_REV:
867                         threshold = Vec4(0.05f, 0.05f, 0.05f, 1.0f);
868                         break;
869
870                 default:
871                         DE_ASSERT(false);
872         }
873
874         // Return value matching the channel order specified by the format
875         if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
876                 return threshold.swizzle(2, 1, 0, 3);
877         else
878                 return threshold;
879 }
880
881 bool isLegalExpandableFormat (tcu::TextureFormat::ChannelType channeltype)
882 {
883         using tcu::TextureFormat;
884
885         switch (channeltype)
886         {
887                 case TextureFormat::UNORM_INT24:
888                 case TextureFormat::UNORM_BYTE_44:
889                 case TextureFormat::UNORM_SHORT_565:
890                 case TextureFormat::UNORM_SHORT_555:
891                 case TextureFormat::UNORM_SHORT_4444:
892                 case TextureFormat::UNORM_SHORT_5551:
893                 case TextureFormat::UNORM_SHORT_1555:
894                 case TextureFormat::UNORM_INT_101010:
895                 case TextureFormat::SNORM_INT_1010102_REV:
896                 case TextureFormat::UNORM_INT_1010102_REV:
897                 case TextureFormat::UNSIGNED_BYTE_44:
898                 case TextureFormat::UNSIGNED_SHORT_565:
899                 case TextureFormat::UNSIGNED_SHORT_4444:
900                 case TextureFormat::UNSIGNED_SHORT_5551:
901                 case TextureFormat::SIGNED_INT_1010102_REV:
902                 case TextureFormat::UNSIGNED_INT_1010102_REV:
903                 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
904                 case TextureFormat::UNSIGNED_INT_999_E5_REV:
905                 case TextureFormat::UNSIGNED_INT_24_8:
906                 case TextureFormat::UNSIGNED_INT_24_8_REV:
907                 case TextureFormat::UNSIGNED_INT24:
908                 case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
909                         return true;
910
911                 case TextureFormat::SNORM_INT8:
912                 case TextureFormat::SNORM_INT16:
913                 case TextureFormat::SNORM_INT32:
914                 case TextureFormat::UNORM_INT8:
915                 case TextureFormat::UNORM_INT16:
916                 case TextureFormat::UNORM_INT32:
917                 case TextureFormat::UNSIGNED_INT_16_8_8:
918                 case TextureFormat::SIGNED_INT8:
919                 case TextureFormat::SIGNED_INT16:
920                 case TextureFormat::SIGNED_INT32:
921                 case TextureFormat::UNSIGNED_INT8:
922                 case TextureFormat::UNSIGNED_INT16:
923                 case TextureFormat::UNSIGNED_INT32:
924                 case TextureFormat::HALF_FLOAT:
925                 case TextureFormat::FLOAT:
926                 case TextureFormat::FLOAT64:
927                         return false;
928
929                 default:
930                         DE_FATAL("Unknown texture format");
931         }
932         return false;
933 }
934
935 bool isSmallerThan8BitFormat (tcu::TextureFormat::ChannelType channeltype)
936 {
937         using tcu::TextureFormat;
938
939         // Note: only checks the legal expandable formats
940         // (i.e, formats that have channels that fall outside
941         // the 8, 16 and 32 bit width)
942         switch (channeltype)
943         {
944                 case TextureFormat::UNORM_BYTE_44:
945                 case TextureFormat::UNORM_SHORT_565:
946                 case TextureFormat::UNORM_SHORT_555:
947                 case TextureFormat::UNORM_SHORT_4444:
948                 case TextureFormat::UNORM_SHORT_5551:
949                 case TextureFormat::UNORM_SHORT_1555:
950                 case TextureFormat::UNSIGNED_BYTE_44:
951                 case TextureFormat::UNSIGNED_SHORT_565:
952                 case TextureFormat::UNSIGNED_SHORT_4444:
953                 case TextureFormat::UNSIGNED_SHORT_5551:
954                         return true;
955
956                 case TextureFormat::UNORM_INT24:
957                 case TextureFormat::UNORM_INT_101010:
958                 case TextureFormat::SNORM_INT_1010102_REV:
959                 case TextureFormat::UNORM_INT_1010102_REV:
960                 case TextureFormat::SIGNED_INT_1010102_REV:
961                 case TextureFormat::UNSIGNED_INT_1010102_REV:
962                 case TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
963                 case TextureFormat::UNSIGNED_INT_999_E5_REV:
964                 case TextureFormat::UNSIGNED_INT_24_8:
965                 case TextureFormat::UNSIGNED_INT_24_8_REV:
966                 case TextureFormat::UNSIGNED_INT24:
967                 case TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
968                         return false;
969
970                 default:
971                         DE_FATAL("Unknown texture format");
972         }
973
974         return false;
975 }
976
977 tcu::TestStatus BlendTestInstance::verifyImage (void)
978 {
979         const tcu::TextureFormat        tcuColorFormat          = mapVkFormat(m_colorFormat);
980         const tcu::TextureFormat        tcuColorFormat64        = mapVkFormat(VK_FORMAT_R64G64B64A64_SFLOAT);
981         const tcu::TextureFormat        tcuColorFormat8         = mapVkFormat(VK_FORMAT_R8G8B8A8_UNORM);
982         const tcu::TextureFormat        tcuDepthFormat          = tcu::TextureFormat(); // Undefined depth/stencil format
983         const ColorVertexShader         vertexShader;
984         const ColorFragmentShader       fragmentShader          (tcuColorFormat, tcuDepthFormat);
985         const rr::Program                       program                         (&vertexShader, &fragmentShader);
986         ReferenceRenderer                       refRenderer                     (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
987         ReferenceRenderer                       refRenderer64           (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat64, tcuDepthFormat, &program);
988         ReferenceRenderer                       refRenderer8            (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat8, tcuDepthFormat, &program);
989         bool                                            compareOk                       = false;
990
991         // Render reference image
992         {
993                 for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
994                 {
995                         const VkPipelineColorBlendAttachmentState& blendState = m_blendStates[quadNdx];
996
997                         // Set blend state
998                         rr::RenderState renderState                                     (refRenderer.getViewportState());
999                         renderState.fragOps.blendMode                           = rr::BLENDMODE_STANDARD;
1000                         renderState.fragOps.blendRGBState.srcFunc       = mapVkBlendFactor(blendState.srcColorBlendFactor);
1001                         renderState.fragOps.blendRGBState.dstFunc       = mapVkBlendFactor(blendState.dstColorBlendFactor);
1002                         renderState.fragOps.blendRGBState.equation      = mapVkBlendOp(blendState.colorBlendOp);
1003                         renderState.fragOps.blendAState.srcFunc         = mapVkBlendFactor(blendState.srcAlphaBlendFactor);
1004                         renderState.fragOps.blendAState.dstFunc         = mapVkBlendFactor(blendState.dstAlphaBlendFactor);
1005                         renderState.fragOps.blendAState.equation        = mapVkBlendOp(blendState.alphaBlendOp);
1006                         renderState.fragOps.blendColor                          = BlendTest::s_blendConst;
1007                         renderState.fragOps.colorMask                           = mapVkColorComponentFlags(BlendTest::s_colorWriteMasks[quadNdx]);
1008
1009                         refRenderer.draw(renderState,
1010                                                         rr::PRIMITIVETYPE_TRIANGLES,
1011                                                         std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
1012                                                                                                          m_vertices.begin() + (quadNdx + 1) * 6));
1013
1014                         if (isLegalExpandableFormat(tcuColorFormat.type))
1015                         {
1016                                 refRenderer64.draw(renderState,
1017                                                                    rr::PRIMITIVETYPE_TRIANGLES,
1018                                                                    std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
1019                                                                    m_vertices.begin() + (quadNdx + 1) * 6));
1020
1021                                 if (isSmallerThan8BitFormat(tcuColorFormat.type))
1022                                         refRenderer8.draw(renderState,
1023                                                                           rr::PRIMITIVETYPE_TRIANGLES,
1024                                                                           std::vector<Vertex4RGBA>(m_vertices.begin() + quadNdx * 6,
1025                                                                           m_vertices.begin() + (quadNdx + 1) * 6));
1026                         }
1027                 }
1028         }
1029
1030         // Compare result with reference image
1031         {
1032                 const DeviceInterface&                          vk                                                      = m_context.getDeviceInterface();
1033                 const VkDevice                                          vkDevice                                        = m_context.getDevice();
1034                 const VkQueue                                           queue                                           = m_context.getUniversalQueue();
1035                 const deUint32                                          queueFamilyIndex                        = m_context.getUniversalQueueFamilyIndex();
1036                 SimpleAllocator                                         allocator                                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1037                 de::UniquePtr<tcu::TextureLevel>        result                                          (readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_colorImage, m_colorFormat, m_renderSize).release());
1038                 const tcu::Vec4                                         threshold                                       (getFormatThreshold(tcuColorFormat));
1039                 tcu::TextureLevel                                       refLevel;
1040
1041                 refLevel.setStorage(tcuColorFormat, m_renderSize.x(), m_renderSize.y(), 1);
1042
1043                 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1044                                                                                            "FloatImageCompare",
1045                                                                                            "Image comparison",
1046                                                                                            refRenderer.getAccess(),
1047                                                                                            result->getAccess(),
1048                                                                                            threshold,
1049                                                                                            tcu::COMPARE_LOG_RESULT);
1050
1051                 if (isLegalExpandableFormat(tcuColorFormat.type))
1052                 {
1053                         if (!compareOk && isSmallerThan8BitFormat(tcuColorFormat.type))
1054                         {
1055                                 // Convert to target format
1056                                 tcu::copy(refLevel.getAccess(), refRenderer8.getAccess());
1057
1058                                 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1059                                                                                                            "FloatImageCompare",
1060                                                                                                            "Image comparison, 8 bit intermediate format",
1061                                                                                                            refLevel.getAccess(),
1062                                                                                                            result->getAccess(),
1063                                                                                                            threshold,
1064                                                                                                            tcu::COMPARE_LOG_RESULT);
1065                         }
1066
1067                         if (!compareOk)
1068                         {
1069                                 // Convert to target format
1070                                 tcu::copy(refLevel.getAccess(), refRenderer64.getAccess());
1071
1072                                 compareOk = tcu::floatThresholdCompare(m_context.getTestContext().getLog(),
1073                                                                                                            "FloatImageCompare",
1074                                                                                                            "Image comparison, 64 bit intermediate format",
1075                                                                                                            refLevel.getAccess(),
1076                                                                                                            result->getAccess(),
1077                                                                                                            threshold,
1078                                                                                                            tcu::COMPARE_LOG_RESULT);
1079                         }
1080                 }
1081         }
1082
1083         if (compareOk)
1084                 return tcu::TestStatus::pass("Result image matches reference");
1085         else
1086                 return tcu::TestStatus::fail("Image mismatch");
1087 }
1088
1089 } // anonymous
1090
1091 std::string getBlendStateName (const VkPipelineColorBlendAttachmentState& blendState)
1092 {
1093         const char* shortBlendFactorNames[] =
1094         {
1095                 "z",            // VK_BLEND_ZERO
1096                 "o",            // VK_BLEND_ONE
1097                 "sc",           // VK_BLEND_SRC_COLOR
1098                 "1msc",         // VK_BLEND_ONE_MINUS_SRC_COLOR
1099                 "dc",           // VK_BLEND_DEST_COLOR
1100                 "1mdc",         // VK_BLEND_ONE_MINUS_DEST_COLOR
1101                 "sa",           // VK_BLEND_SRC_ALPHA
1102                 "1msa",         // VK_BLEND_ONE_MINUS_SRC_ALPHA
1103                 "da",           // VK_BLEND_DEST_ALPHA
1104                 "1mda",         // VK_BLEND_ONE_MINUS_DEST_ALPHA
1105                 "cc",           // VK_BLEND_CONSTANT_COLOR
1106                 "1mcc",         // VK_BLEND_ONE_MINUS_CONSTANT_COLOR
1107                 "ca",           // VK_BLEND_CONSTANT_ALPHA
1108                 "1mca",         // VK_BLEND_ONE_MINUS_CONSTANT_ALPHA
1109                 "sas"           // VK_BLEND_SRC_ALPHA_SATURATE
1110         };
1111
1112         const char* blendOpNames[] =
1113         {
1114                 "add",          // VK_BLEND_OP_ADD
1115                 "sub",          // VK_BLEND_OP_SUBTRACT
1116                 "rsub",         // VK_BLEND_OP_REVERSE_SUBTRACT
1117                 "min",          // VK_BLEND_OP_MIN
1118                 "max",          // VK_BLEND_OP_MAX
1119         };
1120
1121         std::ostringstream shortName;
1122
1123         shortName << "color_" << shortBlendFactorNames[blendState.srcColorBlendFactor] << "_" << shortBlendFactorNames[blendState.dstColorBlendFactor] << "_" << blendOpNames[blendState.colorBlendOp];
1124         shortName << "_alpha_" << shortBlendFactorNames[blendState.srcAlphaBlendFactor] << "_" << shortBlendFactorNames[blendState.dstAlphaBlendFactor] << "_" << blendOpNames[blendState.alphaBlendOp];
1125
1126         return shortName.str();
1127 }
1128
1129 std::string getBlendStateSetName (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1130 {
1131         std::ostringstream name;
1132
1133         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1134         {
1135                 name << getBlendStateName(blendStates[quadNdx]);
1136
1137                 if (quadNdx < BlendTest::QUAD_COUNT - 1)
1138                         name << "-";
1139         }
1140
1141         return name.str();
1142 }
1143
1144 std::string getBlendStateSetDescription (const VkPipelineColorBlendAttachmentState blendStates[BlendTest::QUAD_COUNT])
1145 {
1146         std::ostringstream description;
1147
1148         description << "Draws " << BlendTest::QUAD_COUNT << " quads with the following blend states:\n";
1149
1150         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1151                 description << blendStates[quadNdx] << "\n";
1152
1153         return description.str();
1154 }
1155
1156 std::string getFormatCaseName (VkFormat format)
1157 {
1158         const std::string fullName = getFormatName(format);
1159
1160         DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
1161
1162         return de::toLower(fullName.substr(10));
1163 }
1164
1165 tcu::TestCaseGroup* createBlendTests (tcu::TestContext& testCtx)
1166 {
1167         const deUint32 blendStatesPerFormat = 100 * BlendTest::QUAD_COUNT;
1168
1169         // Formats that are dEQP-compatible, non-integer and uncompressed
1170         const VkFormat blendFormats[] =
1171         {
1172                 VK_FORMAT_R4G4_UNORM_PACK8,
1173                 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1174                 VK_FORMAT_R5G6B5_UNORM_PACK16,
1175                 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
1176                 VK_FORMAT_R8_UNORM,
1177                 VK_FORMAT_R8_SNORM,
1178                 VK_FORMAT_R8_SRGB,
1179                 VK_FORMAT_R8G8_UNORM,
1180                 VK_FORMAT_R8G8_SNORM,
1181                 VK_FORMAT_R8G8_SRGB,
1182                 VK_FORMAT_R8G8B8_UNORM,
1183                 VK_FORMAT_R8G8B8_SNORM,
1184                 VK_FORMAT_R8G8B8_SRGB,
1185                 VK_FORMAT_R8G8B8A8_UNORM,
1186                 VK_FORMAT_R8G8B8A8_SNORM,
1187                 VK_FORMAT_R8G8B8A8_SRGB,
1188                 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
1189                 VK_FORMAT_R16_UNORM,
1190                 VK_FORMAT_R16_SNORM,
1191                 VK_FORMAT_R16_SFLOAT,
1192                 VK_FORMAT_R16G16_UNORM,
1193                 VK_FORMAT_R16G16_SNORM,
1194                 VK_FORMAT_R16G16_SFLOAT,
1195                 VK_FORMAT_R16G16B16_UNORM,
1196                 VK_FORMAT_R16G16B16_SNORM,
1197                 VK_FORMAT_R16G16B16_SFLOAT,
1198                 VK_FORMAT_R16G16B16A16_UNORM,
1199                 VK_FORMAT_R16G16B16A16_SNORM,
1200                 VK_FORMAT_R16G16B16A16_SFLOAT,
1201                 VK_FORMAT_R32_SFLOAT,
1202                 VK_FORMAT_R32G32_SFLOAT,
1203                 VK_FORMAT_R32G32B32_SFLOAT,
1204                 VK_FORMAT_R32G32B32A32_SFLOAT,
1205                 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
1206                 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
1207                 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
1208                 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
1209         };
1210
1211         de::MovePtr<tcu::TestCaseGroup>         blendTests              (new tcu::TestCaseGroup(testCtx, "blend", "Blend tests"));
1212         de::MovePtr<tcu::TestCaseGroup>         formatTests             (new tcu::TestCaseGroup(testCtx, "format", "Uses different blend formats"));
1213         BlendStateUniqueRandomIterator          blendStateItr   (blendStatesPerFormat, 123);
1214
1215         for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(blendFormats); formatNdx++)
1216         {
1217                 const VkFormat                                  format                  = blendFormats[formatNdx];
1218                 de::MovePtr<tcu::TestCaseGroup> formatTest              (new tcu::TestCaseGroup(testCtx,
1219                                                                                                                                                                 getFormatCaseName(format).c_str(),
1220                                                                                                                                                                 (std::string("Uses format ") + getFormatName(format)).c_str()));
1221                 de::MovePtr<tcu::TestCaseGroup> blendStateTests;
1222                 {
1223                         std::ostringstream blendStateDescription;
1224                         blendStateDescription << "Combines blend factors, operators and channel write masks. The constant color used in all tests is " << BlendTest::s_blendConst;
1225                         blendStateTests = de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "states", blendStateDescription.str().c_str()));
1226                 }
1227
1228                 blendStateItr.reset();
1229
1230                 while (blendStateItr.hasNext())
1231                 {
1232                         VkPipelineColorBlendAttachmentState quadBlendConfigs[BlendTest::QUAD_COUNT];
1233
1234                         for (int quadNdx = 0; quadNdx < BlendTest::QUAD_COUNT; quadNdx++)
1235                         {
1236                                 quadBlendConfigs[quadNdx]                                       = blendStateItr.next();
1237                                 quadBlendConfigs[quadNdx].colorWriteMask        = BlendTest::s_colorWriteMasks[quadNdx];
1238                         }
1239
1240                         blendStateTests->addChild(new BlendTest(testCtx,
1241                                                                                                         getBlendStateSetName(quadBlendConfigs),
1242                                                                                                         getBlendStateSetDescription(quadBlendConfigs),
1243                                                                                                         format,
1244                                                                                                         quadBlendConfigs));
1245                 }
1246                 formatTest->addChild(blendStateTests.release());
1247                 formatTests->addChild(formatTest.release());
1248         }
1249         blendTests->addChild(formatTests.release());
1250
1251         return blendTests.release();
1252 }
1253
1254 } // pipeline
1255 } // vkt