Merge vk-gl-cts/vulkan-cts-1.0.1 into vk-gl-cts/vulkan-cts-1.0.2
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / pipeline / vktPipelineMultisampleTests.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 Multisample Tests
23  *//*--------------------------------------------------------------------*/
24
25 #include "vktPipelineMultisampleTests.hpp"
26 #include "vktPipelineMultisampleImageTests.hpp"
27 #include "vktPipelineClearUtil.hpp"
28 #include "vktPipelineImageUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktPipelineReferenceRenderer.hpp"
31 #include "vktTestCase.hpp"
32 #include "vktTestCaseUtil.hpp"
33 #include "vkImageUtil.hpp"
34 #include "vkMemUtil.hpp"
35 #include "vkPrograms.hpp"
36 #include "vkQueryUtil.hpp"
37 #include "vkRef.hpp"
38 #include "vkRefUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "deUniquePtr.hpp"
41 #include "deSharedPtr.hpp"
42 #include "deStringUtil.hpp"
43 #include "deMemory.h"
44
45 #include <sstream>
46 #include <vector>
47 #include <map>
48
49 namespace vkt
50 {
51 namespace pipeline
52 {
53
54 using namespace vk;
55
56 namespace
57 {
58 enum GeometryType
59 {
60         GEOMETRY_TYPE_OPAQUE_TRIANGLE,
61         GEOMETRY_TYPE_OPAQUE_LINE,
62         GEOMETRY_TYPE_OPAQUE_POINT,
63         GEOMETRY_TYPE_OPAQUE_QUAD,
64         GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,        //!< placed at z = 0.5
65         GEOMETRY_TYPE_TRANSLUCENT_QUAD,
66         GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
67         GEOMETRY_TYPE_INVISIBLE_QUAD,
68         GEOMETRY_TYPE_GRADIENT_QUAD
69 };
70
71 enum TestModeBits
72 {
73         TEST_MODE_DEPTH_BIT             = 1u,
74         TEST_MODE_STENCIL_BIT   = 2u,
75 };
76 typedef deUint32 TestModeFlags;
77
78 void                                                                    initMultisamplePrograms                         (SourceCollections& sources, GeometryType geometryType);
79 bool                                                                    isSupportedSampleCount                          (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
80 bool                                                                    isSupportedDepthStencilFormat           (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
81 VkPipelineColorBlendAttachmentState             getDefaultColorBlendAttachmentState     (void);
82 deUint32                                                                getUniqueColorsCount                            (const tcu::ConstPixelBufferAccess& image);
83 VkImageAspectFlags                                              getImageAspectFlags                                     (const VkFormat format);
84 VkPrimitiveTopology                                             getPrimitiveTopology                            (const GeometryType geometryType);
85 std::vector<Vertex4RGBA>                                generateVertices                                        (const GeometryType geometryType);
86 VkFormat                                                                findSupportedDepthStencilFormat         (Context& context, const bool useDepth, const bool useStencil);
87
88 class MultisampleTest : public vkt::TestCase
89 {
90 public:
91
92                                                                                                 MultisampleTest                                         (tcu::TestContext&                                                              testContext,
93                                                                                                                                                                          const std::string&                                                             name,
94                                                                                                                                                                          const std::string&                                                             description,
95                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
96                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
97                                                                                                                                                                          GeometryType                                                                   geometryType);
98         virtual                                                                         ~MultisampleTest                                        (void) {}
99
100         virtual void                                                            initPrograms                                            (SourceCollections& programCollection) const;
101         virtual TestInstance*                                           createInstance                                          (Context& context) const;
102
103 protected:
104         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
105                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
106                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
107                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
108                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const = 0;
109         VkPipelineMultisampleStateCreateInfo            m_multisampleStateParams;
110         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
111         const GeometryType                                                      m_geometryType;
112         std::vector<VkSampleMask>                                       m_sampleMask;
113 };
114
115 class RasterizationSamplesTest : public MultisampleTest
116 {
117 public:
118                                                                                                 RasterizationSamplesTest                        (tcu::TestContext&              testContext,
119                                                                                                                                                                          const std::string&             name,
120                                                                                                                                                                          const std::string&             description,
121                                                                                                                                                                          VkSampleCountFlagBits  rasterizationSamples,
122                                                                                                                                                                          GeometryType                   geometryType,
123                                                                                                                                                                          TestModeFlags                  modeFlags                               = 0u);
124         virtual                                                                         ~RasterizationSamplesTest                       (void) {}
125
126 protected:
127         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
128                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
129                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
130                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
131                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
132
133         static VkPipelineMultisampleStateCreateInfo     getRasterizationSamplesStateParams      (VkSampleCountFlagBits rasterizationSamples);
134
135         const TestModeFlags                                                     m_modeFlags;
136 };
137
138 class MinSampleShadingTest : public MultisampleTest
139 {
140 public:
141                                                                                                 MinSampleShadingTest                            (tcu::TestContext&              testContext,
142                                                                                                                                                                          const std::string&             name,
143                                                                                                                                                                          const std::string&             description,
144                                                                                                                                                                          VkSampleCountFlagBits  rasterizationSamples,
145                                                                                                                                                                          float                                  minSampleShading,
146                                                                                                                                                                          GeometryType                   geometryType);
147         virtual                                                                         ~MinSampleShadingTest                           (void) {}
148
149 protected:
150         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
151                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
152                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
153                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
154                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
155
156         static VkPipelineMultisampleStateCreateInfo     getMinSampleShadingStateParams          (VkSampleCountFlagBits rasterizationSamples, float minSampleShading);
157 };
158
159 class SampleMaskTest : public MultisampleTest
160 {
161 public:
162                                                                                                 SampleMaskTest                                          (tcu::TestContext&                                      testContext,
163                                                                                                                                                                          const std::string&                                     name,
164                                                                                                                                                                          const std::string&                                     description,
165                                                                                                                                                                          VkSampleCountFlagBits                          rasterizationSamples,
166                                                                                                                                                                          const std::vector<VkSampleMask>&       sampleMask,
167                                                                                                                                                                          GeometryType                                           geometryType);
168
169         virtual                                                                         ~SampleMaskTest                                         (void) {}
170
171 protected:
172         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
173                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
174                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
175                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
176                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
177
178         static VkPipelineMultisampleStateCreateInfo     getSampleMaskStateParams                        (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
179 };
180
181 class AlphaToOneTest : public MultisampleTest
182 {
183 public:
184                                                                                                 AlphaToOneTest                                  (tcu::TestContext&                                      testContext,
185                                                                                                                                                                  const std::string&                                     name,
186                                                                                                                                                                  const std::string&                                     description,
187                                                                                                                                                                  VkSampleCountFlagBits                          rasterizationSamples);
188
189         virtual                                                                         ~AlphaToOneTest                                 (void) {}
190
191 protected:
192         virtual TestInstance*                                           createMultisampleTestInstance   (Context&                                                                               context,
193                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
194                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
195                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
196                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
197
198         static VkPipelineMultisampleStateCreateInfo     getAlphaToOneStateParams                (VkSampleCountFlagBits rasterizationSamples);
199         static VkPipelineColorBlendAttachmentState      getAlphaToOneBlendState                 (void);
200 };
201
202 class AlphaToCoverageTest : public MultisampleTest
203 {
204 public:
205                                                                                                 AlphaToCoverageTest                             (tcu::TestContext&              testContext,
206                                                                                                                                                                  const std::string&             name,
207                                                                                                                                                                  const std::string&             description,
208                                                                                                                                                                  VkSampleCountFlagBits  rasterizationSamples,
209                                                                                                                                                                  GeometryType                   geometryType);
210
211         virtual                                                                         ~AlphaToCoverageTest                    (void) {}
212
213 protected:
214         virtual TestInstance*                                           createMultisampleTestInstance   (Context&                                                                               context,
215                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
216                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
217                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
218                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
219
220         static VkPipelineMultisampleStateCreateInfo     getAlphaToCoverageStateParams   (VkSampleCountFlagBits rasterizationSamples);
221
222         GeometryType                                                            m_geometryType;
223 };
224
225 typedef de::SharedPtr<Unique<VkPipeline> > VkPipelineSp;
226
227 class MultisampleRenderer
228 {
229 public:
230                                                                                                 MultisampleRenderer                     (Context&                                                                               context,
231                                                                                                                                                          const VkFormat                                                                 colorFormat,
232                                                                                                                                                          const tcu::IVec2&                                                              renderSize,
233                                                                                                                                                          const VkPrimitiveTopology                                              topology,
234                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
235                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
236                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState);
237
238                                                                                                 MultisampleRenderer                     (Context&                                                                               context,
239                                                                                                                                                          const VkFormat                                                                 colorFormat,
240                                                                                                                                                          const VkFormat                                                                 depthStencilFormat,
241                                                                                                                                                          const tcu::IVec2&                                                              renderSize,
242                                                                                                                                                          const bool                                                                             useDepth,
243                                                                                                                                                          const bool                                                                             useStencil,
244                                                                                                                                                          const deUint32                                                                 numTopologies,
245                                                                                                                                                          const VkPrimitiveTopology*                                             pTopology,
246                                                                                                                                                          const std::vector<Vertex4RGBA>*                                pVertices,
247                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
248                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState);
249
250         virtual                                                                         ~MultisampleRenderer            (void);
251
252         de::MovePtr<tcu::TextureLevel>                          render                                          (void);
253
254 protected:
255         void                                                                            initialize                                      (Context&                                                                               context,
256                                                                                                                                                          const deUint32                                                                 numTopologies,
257                                                                                                                                                          const VkPrimitiveTopology*                                             pTopology,
258                                                                                                                                                          const std::vector<Vertex4RGBA>*                                pVertices);
259
260         Context&                                                                        m_context;
261
262         const VkFormat                                                          m_colorFormat;
263         const VkFormat                                                          m_depthStencilFormat;
264         tcu::IVec2                                                                      m_renderSize;
265         const bool                                                                      m_useDepth;
266         const bool                                                                      m_useStencil;
267
268         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
269         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
270
271         Move<VkImage>                                                           m_colorImage;
272         de::MovePtr<Allocation>                                         m_colorImageAlloc;
273         Move<VkImageView>                                                       m_colorAttachmentView;
274
275         Move<VkImage>                                                           m_resolveImage;
276         de::MovePtr<Allocation>                                         m_resolveImageAlloc;
277         Move<VkImageView>                                                       m_resolveAttachmentView;
278
279         Move<VkImage>                                                           m_depthStencilImage;
280         de::MovePtr<Allocation>                                         m_depthStencilImageAlloc;
281         Move<VkImageView>                                                       m_depthStencilAttachmentView;
282
283         Move<VkRenderPass>                                                      m_renderPass;
284         Move<VkFramebuffer>                                                     m_framebuffer;
285
286         Move<VkShaderModule>                                            m_vertexShaderModule;
287         Move<VkShaderModule>                                            m_fragmentShaderModule;
288
289         Move<VkBuffer>                                                          m_vertexBuffer;
290         de::MovePtr<Allocation>                                         m_vertexBufferAlloc;
291
292         Move<VkPipelineLayout>                                          m_pipelineLayout;
293         std::vector<VkPipelineSp>                                       m_graphicsPipelines;
294
295         Move<VkCommandPool>                                                     m_cmdPool;
296         Move<VkCommandBuffer>                                           m_cmdBuffer;
297
298         Move<VkFence>                                                           m_fence;
299 };
300
301 class RasterizationSamplesInstance : public vkt::TestInstance
302 {
303 public:
304                                                                                 RasterizationSamplesInstance    (Context&                                                                               context,
305                                                                                                                                                  VkPrimitiveTopology                                                    topology,
306                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
307                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
308                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             blendState,
309                                                                                                                                                  const TestModeFlags                                                    modeFlags);
310         virtual                                                         ~RasterizationSamplesInstance   (void) {}
311
312         virtual tcu::TestStatus                         iterate                                                 (void);
313
314 protected:
315         virtual tcu::TestStatus                         verifyImage                                             (const tcu::ConstPixelBufferAccess& result);
316
317         const VkFormat                                          m_colorFormat;
318         const tcu::IVec2                                        m_renderSize;
319         const VkPrimitiveTopology                       m_primitiveTopology;
320         const std::vector<Vertex4RGBA>          m_vertices;
321         const std::vector<Vertex4RGBA>          m_fullQuadVertices;                     //!< used by depth/stencil case
322         const TestModeFlags                                     m_modeFlags;
323         de::MovePtr<MultisampleRenderer>        m_multisampleRenderer;
324 };
325
326 class MinSampleShadingInstance : public vkt::TestInstance
327 {
328 public:
329                                                                                                 MinSampleShadingInstance        (Context&                                                                               context,
330                                                                                                                                                          VkPrimitiveTopology                                                    topology,
331                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
332                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
333                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState);
334         virtual                                                                         ~MinSampleShadingInstance       (void) {}
335
336         virtual tcu::TestStatus                                         iterate                                         (void);
337
338 protected:
339         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& testShadingImage,
340                                                                                                                                                          const tcu::ConstPixelBufferAccess& minShadingImage,
341                                                                                                                                                          const tcu::ConstPixelBufferAccess& maxShadingImage);
342         const VkFormat                                                          m_colorFormat;
343         const tcu::IVec2                                                        m_renderSize;
344         const VkPrimitiveTopology                                       m_primitiveTopology;
345         const std::vector<Vertex4RGBA>                          m_vertices;
346         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
347         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
348 };
349
350 class SampleMaskInstance : public vkt::TestInstance
351 {
352 public:
353                                                                                                 SampleMaskInstance                      (Context&                                                                               context,
354                                                                                                                                                          VkPrimitiveTopology                                                    topology,
355                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
356                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
357                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState);
358         virtual                                                                         ~SampleMaskInstance                     (void) {}
359
360         virtual tcu::TestStatus                                         iterate                                         (void);
361
362 protected:
363         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& testShadingImage,
364                                                                                                                                                          const tcu::ConstPixelBufferAccess& minShadingImage,
365                                                                                                                                                          const tcu::ConstPixelBufferAccess& maxShadingImage);
366         const VkFormat                                                          m_colorFormat;
367         const tcu::IVec2                                                        m_renderSize;
368         const VkPrimitiveTopology                                       m_primitiveTopology;
369         const std::vector<Vertex4RGBA>                          m_vertices;
370         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
371         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
372 };
373
374 class AlphaToOneInstance : public vkt::TestInstance
375 {
376 public:
377                                                                                                 AlphaToOneInstance                      (Context&                                                                               context,
378                                                                                                                                                          VkPrimitiveTopology                                                    topology,
379                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
380                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
381                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState);
382         virtual                                                                         ~AlphaToOneInstance                     (void) {}
383
384         virtual tcu::TestStatus                                         iterate                                         (void);
385
386 protected:
387         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& alphaOneImage,
388                                                                                                                                                          const tcu::ConstPixelBufferAccess& noAlphaOneImage);
389         const VkFormat                                                          m_colorFormat;
390         const tcu::IVec2                                                        m_renderSize;
391         const VkPrimitiveTopology                                       m_primitiveTopology;
392         const std::vector<Vertex4RGBA>                          m_vertices;
393         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
394         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
395 };
396
397 class AlphaToCoverageInstance : public vkt::TestInstance
398 {
399 public:
400                                                                                                 AlphaToCoverageInstance         (Context&                                                                               context,
401                                                                                                                                                          VkPrimitiveTopology                                                    topology,
402                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
403                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
404                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
405                                                                                                                                                          GeometryType                                                                   geometryType);
406         virtual                                                                         ~AlphaToCoverageInstance        (void) {}
407
408         virtual tcu::TestStatus                                         iterate                                         (void);
409
410 protected:
411         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& result);
412         const VkFormat                                                          m_colorFormat;
413         const tcu::IVec2                                                        m_renderSize;
414         const VkPrimitiveTopology                                       m_primitiveTopology;
415         const std::vector<Vertex4RGBA>                          m_vertices;
416         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
417         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
418         const GeometryType                                                      m_geometryType;
419 };
420
421
422 // Helper functions
423
424 void initMultisamplePrograms (SourceCollections& sources, GeometryType geometryType)
425 {
426         std::ostringstream vertexSource;
427
428         vertexSource <<
429                 "#version 310 es\n"
430                 "layout(location = 0) in vec4 position;\n"
431                 "layout(location = 1) in vec4 color;\n"
432                 "layout(location = 0) out highp vec4 vtxColor;\n"
433                 "void main (void)\n"
434                 "{\n"
435                 "       gl_Position = position;\n"
436                 "       vtxColor = color;\n"
437                 << (geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? "      gl_PointSize = 3.0f;\n"
438                                                                                                                  : "" )
439                 << "}\n";
440
441         static const char* fragmentSource =
442                 "#version 310 es\n"
443                 "layout(location = 0) in highp vec4 vtxColor;\n"
444                 "layout(location = 0) out highp vec4 fragColor;\n"
445                 "void main (void)\n"
446                 "{\n"
447                 "       fragColor = vtxColor;\n"
448                 "}\n";
449
450         sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
451         sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
452 }
453
454 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
455 {
456         VkPhysicalDeviceProperties deviceProperties;
457
458         instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
459
460         return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
461 }
462
463 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
464 {
465         const VkPipelineColorBlendAttachmentState colorBlendState =
466         {
467                 false,                                                                                                          // VkBool32                                     blendEnable;
468                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
469                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
470                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
471                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
472                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
473                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
474                 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
475                         VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
476         };
477
478         return colorBlendState;
479 }
480
481 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
482 {
483         DE_ASSERT(image.getFormat().getPixelSize() == 4);
484
485         std::map<deUint32, deUint32>    histogram; // map<pixel value, number of occurrences>
486         const deUint32                                  pixelCount      = image.getWidth() * image.getHeight() * image.getDepth();
487
488         for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
489         {
490                 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
491
492                 if (histogram.find(pixelValue) != histogram.end())
493                         histogram[pixelValue]++;
494                 else
495                         histogram[pixelValue] = 1;
496         }
497
498         return (deUint32)histogram.size();
499 }
500
501 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
502 {
503         const tcu::TextureFormat tcuFormat = mapVkFormat(format);
504
505         if      (tcuFormat.order == tcu::TextureFormat::DS)             return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
506         else if (tcuFormat.order == tcu::TextureFormat::D)              return VK_IMAGE_ASPECT_DEPTH_BIT;
507         else if (tcuFormat.order == tcu::TextureFormat::S)              return VK_IMAGE_ASPECT_STENCIL_BIT;
508
509         DE_ASSERT(false);
510         return 0u;
511 }
512
513 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
514 {
515         std::vector<Vertex4RGBA> vertices;
516
517         switch (geometryType)
518         {
519                 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
520                 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
521                 {
522                         Vertex4RGBA vertexData[3] =
523                         {
524                                 {
525                                         tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
526                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
527                                 },
528                                 {
529                                         tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
530                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
531                                 },
532                                 {
533                                         tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
534                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
535                                 }
536                         };
537
538                         if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
539                         {
540                                 for (int i = 0; i < 3; i++)
541                                         vertexData[i].color = tcu::Vec4();
542                         }
543
544                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
545                         break;
546                 }
547
548                 case GEOMETRY_TYPE_OPAQUE_LINE:
549                 {
550                         const Vertex4RGBA vertexData[2] =
551                         {
552                                 {
553                                         tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
554                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
555                                 },
556                                 {
557                                         tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
558                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
559                                 }
560                         };
561
562                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
563                         break;
564                 }
565
566                 case GEOMETRY_TYPE_OPAQUE_POINT:
567                 {
568                         const Vertex4RGBA vertex =
569                         {
570                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
571                                 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
572                         };
573
574                         vertices = std::vector<Vertex4RGBA>(1, vertex);
575                         break;
576                 }
577
578                 case GEOMETRY_TYPE_OPAQUE_QUAD:
579                 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
580                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
581                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
582                 case GEOMETRY_TYPE_GRADIENT_QUAD:
583                 {
584                         Vertex4RGBA vertexData[4] =
585                         {
586                                 {
587                                         tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
588                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
589                                 },
590                                 {
591                                         tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
592                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
593                                 },
594                                 {
595                                         tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
596                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
597                                 },
598                                 {
599                                         tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
600                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
601                                 }
602                         };
603
604                         if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
605                         {
606                                 for (int i = 0; i < 4; i++)
607                                         vertexData[i].color.w() = 0.25f;
608                         }
609                         else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
610                         {
611                                 for (int i = 0; i < 4; i++)
612                                         vertexData[i].color.w() = 0.0f;
613                         }
614                         else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
615                         {
616                                 vertexData[0].color.w() = 0.0f;
617                                 vertexData[2].color.w() = 0.0f;
618                         }
619                         else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
620                         {
621                                 for (int i = 0; i < 4; i++)
622                                         vertexData[i].position.z() = 0.5f;
623                         }
624
625                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
626                         break;
627                 }
628
629                 default:
630                         DE_ASSERT(false);
631         }
632         return vertices;
633 }
634
635 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
636 {
637         switch (geometryType)
638         {
639                 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
640                 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:                  return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
641
642                 case GEOMETRY_TYPE_OPAQUE_LINE:                                 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
643                 case GEOMETRY_TYPE_OPAQUE_POINT:                                return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
644
645                 case GEOMETRY_TYPE_OPAQUE_QUAD:
646                 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
647                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
648                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
649                 case GEOMETRY_TYPE_GRADIENT_QUAD:                               return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
650
651                 default:
652                         DE_ASSERT(false);
653                         return VK_PRIMITIVE_TOPOLOGY_LAST;
654         }
655 }
656
657 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
658 {
659         VkFormatProperties formatProps;
660         vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
661         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
662 }
663
664 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
665 {
666         if (useDepth && !useStencil)
667                 return VK_FORMAT_D16_UNORM;             // must be supported
668
669         const InstanceInterface&        vki                     = context.getInstanceInterface();
670         const VkPhysicalDevice          physDevice      = context.getPhysicalDevice();
671
672         // One of these formats must be supported.
673
674         if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
675                 return VK_FORMAT_D24_UNORM_S8_UINT;
676
677         if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
678                 return VK_FORMAT_D32_SFLOAT_S8_UINT;
679
680         return VK_FORMAT_UNDEFINED;
681 }
682
683
684 // MultisampleTest
685
686 MultisampleTest::MultisampleTest (tcu::TestContext&                                                             testContext,
687                                                                   const std::string&                                                    name,
688                                                                   const std::string&                                                    description,
689                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
690                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
691                                                                   GeometryType                                                                  geometryType)
692         : vkt::TestCase                         (testContext, name, description)
693         , m_multisampleStateParams      (multisampleStateParams)
694         , m_colorBlendState                     (blendState)
695         , m_geometryType                        (geometryType)
696 {
697         if (m_multisampleStateParams.pSampleMask)
698         {
699                 // Copy pSampleMask to avoid dependencies with other classes
700
701                 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
702
703                 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
704                         m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
705
706                 m_multisampleStateParams.pSampleMask = m_sampleMask.data();
707         }
708 }
709
710 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
711 {
712         initMultisamplePrograms(programCollection, m_geometryType);
713 }
714
715 TestInstance* MultisampleTest::createInstance (Context& context) const
716 {
717         return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
718 }
719
720
721 // RasterizationSamplesTest
722
723 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&           testContext,
724                                                                                                         const std::string&              name,
725                                                                                                         const std::string&              description,
726                                                                                                         VkSampleCountFlagBits   rasterizationSamples,
727                                                                                                         GeometryType                    geometryType,
728                                                                                                         TestModeFlags                   modeFlags)
729         : MultisampleTest       (testContext, name, description, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
730         , m_modeFlags           (modeFlags)
731 {
732 }
733
734 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
735 {
736         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
737         {
738                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
739                 DE_NULL,                                                                                                        // const void*                                                          pNext;
740                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
741                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
742                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
743                 0.0f,                                                                                                           // float                                                                        minSampleShading;
744                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
745                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
746                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
747         };
748
749         return multisampleStateParams;
750 }
751
752 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&                                                                         context,
753                                                                                                                                            VkPrimitiveTopology                                                  topology,
754                                                                                                                                            const std::vector<Vertex4RGBA>&                              vertices,
755                                                                                                                                            const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
756                                                                                                                                            const VkPipelineColorBlendAttachmentState&   colorBlendState) const
757 {
758         return new RasterizationSamplesInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_modeFlags);
759 }
760
761
762 // MinSampleShadingTest
763
764 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&           testContext,
765                                                                                         const std::string&              name,
766                                                                                         const std::string&              description,
767                                                                                         VkSampleCountFlagBits   rasterizationSamples,
768                                                                                         float                                   minSampleShading,
769                                                                                         GeometryType                    geometryType)
770         : MultisampleTest       (testContext, name, description, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading), getDefaultColorBlendAttachmentState(), geometryType)
771 {
772 }
773
774 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&                                                                             context,
775                                                                                                                                    VkPrimitiveTopology                                                  topology,
776                                                                                                                                    const std::vector<Vertex4RGBA>&                              vertices,
777                                                                                                                                    const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
778                                                                                                                                    const VkPipelineColorBlendAttachmentState&   colorBlendState) const
779 {
780         return new MinSampleShadingInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
781 }
782
783 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading)
784 {
785         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
786         {
787                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
788                 DE_NULL,                                                                                                        // const void*                                                          pNext;
789                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
790                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
791                 true,                                                                                                           // VkBool32                                                                     sampleShadingEnable;
792                 minSampleShading,                                                                                       // float                                                                        minSampleShading;
793                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
794                 false,                                                                                                          //  VkBool32                                                            alphaToCoverageEnable;
795                 false                                                                                                           //  VkBool32                                                            alphaToOneEnable;
796         };
797
798         return multisampleStateParams;
799 }
800
801
802 // SampleMaskTest
803
804 SampleMaskTest::SampleMaskTest (tcu::TestContext&                                       testContext,
805                                                                 const std::string&                                      name,
806                                                                 const std::string&                                      description,
807                                                                 VkSampleCountFlagBits                           rasterizationSamples,
808                                                                 const std::vector<VkSampleMask>&        sampleMask,
809                                                                 GeometryType                                            geometryType)
810         : MultisampleTest       (testContext, name, description, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType)
811 {
812 }
813
814 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&                                                                           context,
815                                                                                                                          VkPrimitiveTopology                                                    topology,
816                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
817                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
818                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const
819 {
820         return new SampleMaskInstance(context, topology,vertices, multisampleStateParams, colorBlendState);
821 }
822
823 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
824 {
825         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
826         {
827                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
828                 DE_NULL,                                                                                                        // const void*                                                          pNext;
829                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
830                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
831                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
832                 0.0f,                                                                                                           // float                                                                        minSampleShading;
833                 sampleMask.data(),                                                                                      // const VkSampleMask*                                          pSampleMask;
834                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
835                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
836         };
837
838         return multisampleStateParams;
839 }
840
841
842 // AlphaToOneTest
843
844 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&               testContext,
845                                                                 const std::string&              name,
846                                                                 const std::string&              description,
847                                                                 VkSampleCountFlagBits   rasterizationSamples)
848         : MultisampleTest       (testContext, name, description, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD)
849 {
850 }
851
852 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&                                                                           context,
853                                                                                                                          VkPrimitiveTopology                                                    topology,
854                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
855                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
856                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const
857 {
858         return new AlphaToOneInstance(context, topology, vertices, multisampleStateParams, colorBlendState);
859 }
860
861 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
862 {
863         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
864         {
865                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
866                 DE_NULL,                                                                                                        // const void*                                                          pNext;
867                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
868                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
869                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
870                 0.0f,                                                                                                           // float                                                                        minSampleShading;
871                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
872                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
873                 true                                                                                                            // VkBool32                                                                     alphaToOneEnable;
874         };
875
876         return multisampleStateParams;
877 }
878
879 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
880 {
881         const VkPipelineColorBlendAttachmentState colorBlendState =
882         {
883                 true,                                                                                                           // VkBool32                                     blendEnable;
884                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                      // VkBlendFactor                        srcColorBlendFactor;
885                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                            // VkBlendFactor                        dstColorBlendFactor;
886                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
887                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                      // VkBlendFactor                        srcAlphaBlendFactor;
888                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                            // VkBlendFactor                        dstAlphaBlendFactor;
889                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
890                 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
891                         VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
892         };
893
894         return colorBlendState;
895 }
896
897
898 // AlphaToCoverageTest
899
900 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&                     testContext,
901                                                                                   const std::string&            name,
902                                                                                   const std::string&            description,
903                                                                                   VkSampleCountFlagBits         rasterizationSamples,
904                                                                                   GeometryType                          geometryType)
905         : MultisampleTest       (testContext, name, description, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType)
906         , m_geometryType        (geometryType)
907 {
908 }
909
910 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&                                                                              context,
911                                                                                                                                   VkPrimitiveTopology                                                   topology,
912                                                                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
913                                                                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
914                                                                                                                                   const VkPipelineColorBlendAttachmentState&    colorBlendState) const
915 {
916         return new AlphaToCoverageInstance(context, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType);
917 }
918
919 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
920 {
921         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
922         {
923                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
924                 DE_NULL,                                                                                                        // const void*                                                          pNext;
925                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
926                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
927                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
928                 0.0f,                                                                                                           // float                                                                        minSampleShading;
929                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
930                 true,                                                                                                           // VkBool32                                                                     alphaToCoverageEnable;
931                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
932         };
933
934         return multisampleStateParams;
935 }
936
937 // RasterizationSamplesInstance
938
939 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&                                                                            context,
940                                                                                                                         VkPrimitiveTopology                                                             topology,
941                                                                                                                         const std::vector<Vertex4RGBA>&                                 vertices,
942                                                                                                                         const VkPipelineMultisampleStateCreateInfo&             multisampleStateParams,
943                                                                                                                         const VkPipelineColorBlendAttachmentState&              blendState,
944                                                                                                                         const TestModeFlags                                                             modeFlags)
945         : vkt::TestInstance             (context)
946         , m_colorFormat                 (VK_FORMAT_R8G8B8A8_UNORM)
947         , m_renderSize                  (32, 32)
948         , m_primitiveTopology   (topology)
949         , m_vertices                    (vertices)
950         , m_fullQuadVertices    (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
951         , m_modeFlags                   (modeFlags)
952 {
953         if (m_modeFlags != 0)
954         {
955                 const bool              useDepth                        = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
956                 const bool              useStencil                      = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
957                 const VkFormat  depthStencilFormat      = findSupportedDepthStencilFormat(context, useDepth, useStencil);
958
959                 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
960                         TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
961
962                 const VkPrimitiveTopology               pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
963                 const std::vector<Vertex4RGBA>  pVertices[2] = { m_vertices, m_fullQuadVertices };
964
965                 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
966                         new MultisampleRenderer(
967                                 context, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil, 2u, pTopology, pVertices, multisampleStateParams, blendState));
968         }
969         else
970         {
971                 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
972                         new MultisampleRenderer(context, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams, blendState));
973         }
974 }
975
976 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
977 {
978         de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
979         return verifyImage(level->getAccess());
980 }
981
982 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
983 {
984         // Verify range of unique pixels
985         {
986                 const deUint32  numUniqueColors = getUniqueColorsCount(result);
987                 const deUint32  minUniqueColors = 3;
988
989                 tcu::TestLog& log = m_context.getTestContext().getLog();
990
991                 log << tcu::TestLog::Message
992                         << "\nMin. unique colors expected: " << minUniqueColors << "\n"
993                         << "Unique colors found: " << numUniqueColors << "\n"
994                         << tcu::TestLog::EndMessage;
995
996                 if (numUniqueColors < minUniqueColors)
997                         return tcu::TestStatus::fail("Unique colors out of expected bounds");
998         }
999
1000         // Verify shape of the rendered primitive (fuzzy-compare)
1001         {
1002                 const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
1003                 const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat();
1004                 const ColorVertexShader         vertexShader;
1005                 const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
1006                 const rr::Program                       program                 (&vertexShader, &fragmentShader);
1007                 ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
1008                 rr::RenderState                         renderState             (refRenderer.getViewportState());
1009
1010                 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
1011                 {
1012                         VkPhysicalDeviceProperties deviceProperties;
1013
1014                         m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
1015
1016                         // gl_PointSize is clamped to pointSizeRange
1017                         renderState.point.pointSize = deFloatMin(3.0f, deviceProperties.limits.pointSizeRange[1]);
1018                 }
1019
1020                 if (m_modeFlags == 0)
1021                 {
1022                         refRenderer.colorClear(tcu::Vec4(0.0f));
1023                         refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1024                 }
1025                 else
1026                 {
1027                         // For depth/stencil case the primitive is invisible and the surroundings are filled red.
1028                         refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
1029                         refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
1030                 }
1031
1032                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
1033                         return tcu::TestStatus::fail("Primitive has unexpected shape");
1034         }
1035
1036         return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
1037 }
1038
1039
1040 // MinSampleShadingInstance
1041
1042 MinSampleShadingInstance::MinSampleShadingInstance (Context&                                                                    context,
1043                                                                                                         VkPrimitiveTopology                                                     topology,
1044                                                                                                         const std::vector<Vertex4RGBA>&                         vertices,
1045                                                                                                         const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
1046                                                                                                         const VkPipelineColorBlendAttachmentState&      colorBlendState)
1047         : vkt::TestInstance                     (context)
1048         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
1049         , m_renderSize                          (32, 32)
1050         , m_primitiveTopology           (topology)
1051         , m_vertices                            (vertices)
1052         , m_multisampleStateParams      (multisampleStateParams)
1053         , m_colorBlendState                     (colorBlendState)
1054 {
1055         VkPhysicalDeviceFeatures deviceFeatures;
1056
1057         m_context.getInstanceInterface().getPhysicalDeviceFeatures(m_context.getPhysicalDevice(), &deviceFeatures);
1058
1059         if (!deviceFeatures.sampleRateShading)
1060                 throw tcu::NotSupportedError("Sample shading is not supported");
1061 }
1062
1063 tcu::TestStatus MinSampleShadingInstance::iterate (void)
1064 {
1065         de::MovePtr<tcu::TextureLevel>                          testShadingImage;
1066         de::MovePtr<tcu::TextureLevel>                          minShadingImage;
1067         de::MovePtr<tcu::TextureLevel>                          maxShadingImage;
1068
1069         // Render with test minSampleShading
1070         {
1071                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1072                 testShadingImage = renderer.render();
1073         }
1074
1075         // Render with minSampleShading = 0.0f
1076         {
1077                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
1078                 multisampleParams.minSampleShading = 0.0f;
1079
1080                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1081                 minShadingImage = renderer.render();
1082         }
1083
1084         // Render with minSampleShading = 1.0f
1085         {
1086                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
1087                 multisampleParams.minSampleShading = 1.0f;
1088
1089                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1090                 maxShadingImage = renderer.render();
1091         }
1092
1093         return verifyImage(testShadingImage->getAccess(), minShadingImage->getAccess(), maxShadingImage->getAccess());
1094 }
1095
1096 tcu::TestStatus MinSampleShadingInstance::verifyImage (const tcu::ConstPixelBufferAccess& testShadingImage, const tcu::ConstPixelBufferAccess& minShadingImage, const tcu::ConstPixelBufferAccess& maxShadingImage)
1097 {
1098         const deUint32  testColorCount  = getUniqueColorsCount(testShadingImage);
1099         const deUint32  minColorCount   = getUniqueColorsCount(minShadingImage);
1100         const deUint32  maxColorCount   = getUniqueColorsCount(maxShadingImage);
1101
1102         tcu::TestLog& log = m_context.getTestContext().getLog();
1103
1104         log << tcu::TestLog::Message
1105                 << "\nColors found: " << testColorCount << "\n"
1106                 << "Min. colors expected: " << minColorCount << "\n"
1107                 << "Max. colors expected: " << maxColorCount << "\n"
1108                 << tcu::TestLog::EndMessage;
1109
1110         if (minColorCount > testColorCount || testColorCount > maxColorCount)
1111                 return tcu::TestStatus::fail("Unique colors out of expected bounds");
1112         else
1113                 return tcu::TestStatus::pass("Unique colors within expected bounds");
1114 }
1115
1116 SampleMaskInstance::SampleMaskInstance (Context&                                                                                context,
1117                                                                                 VkPrimitiveTopology                                                             topology,
1118                                                                                 const std::vector<Vertex4RGBA>&                                 vertices,
1119                                                                                 const VkPipelineMultisampleStateCreateInfo&             multisampleStateParams,
1120                                                                                 const VkPipelineColorBlendAttachmentState&              blendState)
1121         : vkt::TestInstance                     (context)
1122         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
1123         , m_renderSize                          (32, 32)
1124         , m_primitiveTopology           (topology)
1125         , m_vertices                            (vertices)
1126         , m_multisampleStateParams      (multisampleStateParams)
1127         , m_colorBlendState                     (blendState)
1128 {
1129 }
1130
1131 tcu::TestStatus SampleMaskInstance::iterate (void)
1132 {
1133         de::MovePtr<tcu::TextureLevel>                          testSampleMaskImage;
1134         de::MovePtr<tcu::TextureLevel>                          minSampleMaskImage;
1135         de::MovePtr<tcu::TextureLevel>                          maxSampleMaskImage;
1136
1137         // Render with test flags
1138         {
1139                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1140                 testSampleMaskImage = renderer.render();
1141         }
1142
1143         // Render with all flags off
1144         {
1145                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
1146                 const std::vector<VkSampleMask>                 sampleMask                      (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
1147
1148                 multisampleParams.pSampleMask = sampleMask.data();
1149
1150                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1151                 minSampleMaskImage = renderer.render();
1152         }
1153
1154         // Render with all flags on
1155         {
1156                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
1157                 const std::vector<VkSampleMask>                 sampleMask                      (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
1158
1159                 multisampleParams.pSampleMask = sampleMask.data();
1160
1161                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1162                 maxSampleMaskImage = renderer.render();
1163         }
1164
1165         return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
1166 }
1167
1168 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
1169                                                                                                  const tcu::ConstPixelBufferAccess& minSampleMaskImage,
1170                                                                                                  const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
1171 {
1172         const deUint32  testColorCount  = getUniqueColorsCount(testSampleMaskImage);
1173         const deUint32  minColorCount   = getUniqueColorsCount(minSampleMaskImage);
1174         const deUint32  maxColorCount   = getUniqueColorsCount(maxSampleMaskImage);
1175
1176         tcu::TestLog& log = m_context.getTestContext().getLog();
1177
1178         log << tcu::TestLog::Message
1179                 << "\nColors found: " << testColorCount << "\n"
1180                 << "Min. colors expected: " << minColorCount << "\n"
1181                 << "Max. colors expected: " << maxColorCount << "\n"
1182                 << tcu::TestLog::EndMessage;
1183
1184         if (minColorCount > testColorCount || testColorCount > maxColorCount)
1185                 return tcu::TestStatus::fail("Unique colors out of expected bounds");
1186         else
1187                 return tcu::TestStatus::pass("Unique colors within expected bounds");
1188 }
1189
1190 tcu::TestStatus testRasterSamplesConsistency (Context& context, GeometryType geometryType)
1191 {
1192         // Use triangle only.
1193         DE_UNREF(geometryType);
1194
1195         const VkSampleCountFlagBits samples[] =
1196         {
1197                 VK_SAMPLE_COUNT_1_BIT,
1198                 VK_SAMPLE_COUNT_2_BIT,
1199                 VK_SAMPLE_COUNT_4_BIT,
1200                 VK_SAMPLE_COUNT_8_BIT,
1201                 VK_SAMPLE_COUNT_16_BIT,
1202                 VK_SAMPLE_COUNT_32_BIT,
1203                 VK_SAMPLE_COUNT_64_BIT
1204         };
1205
1206         const Vertex4RGBA vertexData[3] =
1207         {
1208                 {
1209                         tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1210                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1211                 },
1212                 {
1213                         tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1214                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1215                 },
1216                 {
1217                         tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1218                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1219                 }
1220         };
1221
1222         const std::vector<Vertex4RGBA>  vertices                        (vertexData, vertexData + 3);
1223         deUint32                                                prevUniqueColors        = 2;
1224         int                                                             renderCount                     = 0;
1225
1226         // Do not render with 1 sample (start with samplesNdx = 1).
1227         for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
1228         {
1229                 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
1230                         continue;
1231
1232                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1233                 {
1234                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1235                         DE_NULL,                                                                                                        // const void*                                                          pNext;
1236                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1237                         samples[samplesNdx],                                                                            // VkSampleCountFlagBits                                        rasterizationSamples;
1238                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1239                         0.0f,                                                                                                           // float                                                                        minSampleShading;
1240                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1241                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
1242                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1243                 };
1244
1245                 MultisampleRenderer                             renderer                (context, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState());
1246                 de::MovePtr<tcu::TextureLevel>  result                  = renderer.render();
1247                 const deUint32                                  uniqueColors    = getUniqueColorsCount(result->getAccess());
1248
1249                 renderCount++;
1250
1251                 if (prevUniqueColors > uniqueColors)
1252                 {
1253                         std::ostringstream message;
1254
1255                         message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
1256                         return tcu::TestStatus::fail(message.str());
1257                 }
1258
1259                 prevUniqueColors = uniqueColors;
1260         }
1261
1262         if (renderCount == 0)
1263                 throw tcu::NotSupportedError("Multisampling is unsupported");
1264
1265         return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
1266 }
1267
1268
1269 // AlphaToOneInstance
1270
1271 AlphaToOneInstance::AlphaToOneInstance (Context&                                                                        context,
1272                                                                                 VkPrimitiveTopology                                                     topology,
1273                                                                                 const std::vector<Vertex4RGBA>&                         vertices,
1274                                                                                 const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
1275                                                                                 const VkPipelineColorBlendAttachmentState&      blendState)
1276         : vkt::TestInstance                     (context)
1277         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
1278         , m_renderSize                          (32, 32)
1279         , m_primitiveTopology           (topology)
1280         , m_vertices                            (vertices)
1281         , m_multisampleStateParams      (multisampleStateParams)
1282         , m_colorBlendState                     (blendState)
1283 {
1284         VkPhysicalDeviceFeatures deviceFeatures;
1285
1286         context.getInstanceInterface().getPhysicalDeviceFeatures(context.getPhysicalDevice(), &deviceFeatures);
1287
1288         if (!deviceFeatures.alphaToOne)
1289                 throw tcu::NotSupportedError("Alpha-to-one is not supported");
1290 }
1291
1292 tcu::TestStatus AlphaToOneInstance::iterate     (void)
1293 {
1294         DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
1295         DE_ASSERT(m_colorBlendState.blendEnable);
1296
1297         de::MovePtr<tcu::TextureLevel>  alphaOneImage;
1298         de::MovePtr<tcu::TextureLevel>  noAlphaOneImage;
1299
1300         // Render with blend enabled and alpha to one on
1301         {
1302                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1303                 alphaOneImage = renderer.render();
1304         }
1305
1306         // Render with blend enabled and alpha to one off
1307         {
1308                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
1309                 multisampleParams.alphaToOneEnable = false;
1310
1311                 MultisampleRenderer renderer (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState);
1312                 noAlphaOneImage = renderer.render();
1313         }
1314
1315         return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
1316 }
1317
1318 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&     alphaOneImage,
1319                                                                                                  const tcu::ConstPixelBufferAccess&     noAlphaOneImage)
1320 {
1321         for (int y = 0; y < m_renderSize.y(); y++)
1322         {
1323                 for (int x = 0; x < m_renderSize.x(); x++)
1324                 {
1325                         if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
1326                         {
1327                                 std::ostringstream message;
1328                                 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
1329                                 return tcu::TestStatus::fail(message.str());
1330                         }
1331                 }
1332         }
1333
1334         return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
1335 }
1336
1337
1338 // AlphaToCoverageInstance
1339
1340 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&                                                                              context,
1341                                                                                                   VkPrimitiveTopology                                                   topology,
1342                                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
1343                                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
1344                                                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
1345                                                                                                   GeometryType                                                                  geometryType)
1346         : vkt::TestInstance                     (context)
1347         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
1348         , m_renderSize                          (32, 32)
1349         , m_primitiveTopology           (topology)
1350         , m_vertices                            (vertices)
1351         , m_multisampleStateParams      (multisampleStateParams)
1352         , m_colorBlendState                     (blendState)
1353         , m_geometryType                        (geometryType)
1354 {
1355 }
1356
1357 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
1358 {
1359         DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
1360
1361         de::MovePtr<tcu::TextureLevel>  result;
1362         MultisampleRenderer                             renderer        (m_context, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState);
1363
1364         result = renderer.render();
1365
1366         return verifyImage(result->getAccess());
1367 }
1368
1369 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&        result)
1370 {
1371         float maxColorValue;
1372
1373         switch (m_geometryType)
1374         {
1375                 case GEOMETRY_TYPE_OPAQUE_QUAD:
1376                         maxColorValue = 1.01f;
1377                         break;
1378
1379                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1380                         maxColorValue = 0.52f;
1381                         break;
1382
1383                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
1384                         maxColorValue = 0.01f;
1385                         break;
1386
1387                 default:
1388                         maxColorValue = 0.0f;
1389                         DE_ASSERT(false);
1390         }
1391
1392         for (int y = 0; y < m_renderSize.y(); y++)
1393         {
1394                 for (int x = 0; x < m_renderSize.x(); x++)
1395                 {
1396                         if (result.getPixel(x, y).x() > maxColorValue)
1397                         {
1398                                 std::ostringstream message;
1399                                 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
1400                                 return tcu::TestStatus::fail(message.str());
1401                         }
1402                 }
1403         }
1404
1405         return tcu::TestStatus::pass("Image matches reference value");
1406 }
1407
1408
1409 // MultisampleRenderer
1410
1411 MultisampleRenderer::MultisampleRenderer (Context&                                                                              context,
1412                                                                                   const VkFormat                                                                colorFormat,
1413                                                                                   const tcu::IVec2&                                                             renderSize,
1414                                                                                   const VkPrimitiveTopology                                             topology,
1415                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
1416                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
1417                                                                                   const VkPipelineColorBlendAttachmentState&    blendState)
1418         : m_context                                     (context)
1419         , m_colorFormat                         (colorFormat)
1420         , m_depthStencilFormat          (VK_FORMAT_UNDEFINED)
1421         , m_renderSize                          (renderSize)
1422         , m_useDepth                            (false)
1423         , m_useStencil                          (false)
1424         , m_multisampleStateParams      (multisampleStateParams)
1425         , m_colorBlendState                     (blendState)
1426 {
1427         initialize(context, 1u, &topology, &vertices);
1428 }
1429
1430 MultisampleRenderer::MultisampleRenderer (Context&                                                                              context,
1431                                                                                   const VkFormat                                                                colorFormat,
1432                                                                                   const VkFormat                                                                depthStencilFormat,
1433                                                                                   const tcu::IVec2&                                                             renderSize,
1434                                                                                   const bool                                                                    useDepth,
1435                                                                                   const bool                                                                    useStencil,
1436                                                                                   const deUint32                                                                numTopologies,
1437                                                                                   const VkPrimitiveTopology*                                    pTopology,
1438                                                                                   const std::vector<Vertex4RGBA>*                               pVertices,
1439                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
1440                                                                                   const VkPipelineColorBlendAttachmentState&    blendState)
1441         : m_context                                     (context)
1442         , m_colorFormat                         (colorFormat)
1443         , m_depthStencilFormat          (depthStencilFormat)
1444         , m_renderSize                          (renderSize)
1445         , m_useDepth                            (useDepth)
1446         , m_useStencil                          (useStencil)
1447         , m_multisampleStateParams      (multisampleStateParams)
1448         , m_colorBlendState                     (blendState)
1449 {
1450         initialize(context, numTopologies, pTopology, pVertices);
1451 }
1452
1453 void MultisampleRenderer::initialize (Context&                                                                  context,
1454                                                                           const deUint32                                                        numTopologies,
1455                                                                           const VkPrimitiveTopology*                            pTopology,
1456                                                                           const std::vector<Vertex4RGBA>*                       pVertices)
1457 {
1458         if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
1459                 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
1460
1461         const DeviceInterface&          vk                                              = context.getDeviceInterface();
1462         const VkDevice                          vkDevice                                = context.getDevice();
1463         const deUint32                          queueFamilyIndex                = context.getUniversalQueueFamilyIndex();
1464         SimpleAllocator                         memAlloc                                (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1465         const VkComponentMapping        componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
1466
1467         // Create color image
1468         {
1469                 const VkImageCreateInfo colorImageParams =
1470                 {
1471                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
1472                         DE_NULL,                                                                                                                                        // const void*                          pNext;
1473                         0u,                                                                                                                                                     // VkImageCreateFlags           flags;
1474                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
1475                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
1476                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                         // VkExtent3D                           extent;
1477                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
1478                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
1479                         m_multisampleStateParams.rasterizationSamples,                                                          // VkSampleCountFlagBits        samples;
1480                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
1481                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,          // VkImageUsageFlags            usage;
1482                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                      // VkSharingMode                        sharingMode;
1483                         1u,                                                                                                                                                     // deUint32                                     queueFamilyIndexCount;
1484                         &queueFamilyIndex,                                                                                                                      // const deUint32*                      pQueueFamilyIndices;
1485                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
1486                 };
1487
1488                 m_colorImage                    = createImage(vk, vkDevice, &colorImageParams);
1489
1490                 // Allocate and bind color image memory
1491                 m_colorImageAlloc               = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
1492                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
1493         }
1494
1495         // Create resolve image
1496         {
1497                 const VkImageCreateInfo resolveImageParams =
1498                 {
1499                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                    // VkStructureType                      sType;
1500                         DE_NULL,                                                                                                                                                // const void*                          pNext;
1501                         0u,                                                                                                                                                             // VkImageCreateFlags           flags;
1502                         VK_IMAGE_TYPE_2D,                                                                                                                               // VkImageType                          imageType;
1503                         m_colorFormat,                                                                                                                                  // VkFormat                                     format;
1504                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                                 // VkExtent3D                           extent;
1505                         1u,                                                                                                                                                             // deUint32                                     mipLevels;
1506                         1u,                                                                                                                                                             // deUint32                                     arrayLayers;
1507                         VK_SAMPLE_COUNT_1_BIT,                                                                                                                  // VkSampleCountFlagBits        samples;
1508                         VK_IMAGE_TILING_OPTIMAL,                                                                                                                // VkImageTiling                        tiling;
1509                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |                 // VkImageUsageFlags            usage;
1510                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1511                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                              // VkSharingMode                        sharingMode;
1512                         1u,                                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
1513                         &queueFamilyIndex,                                                                                                                              // const deUint32*                      pQueueFamilyIndices;
1514                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                               // VkImageLayout                        initialLayout;
1515                 };
1516
1517                 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
1518
1519                 // Allocate and bind resolve image memory
1520                 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
1521                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
1522         }
1523
1524         // Create a depth/stencil image
1525         if (m_useDepth || m_useStencil)
1526         {
1527                 const VkImageCreateInfo depthStencilImageParams =
1528                 {
1529                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                    // VkStructureType                      sType;
1530                         DE_NULL,                                                                                                                                                // const void*                          pNext;
1531                         0u,                                                                                                                                                             // VkImageCreateFlags           flags;
1532                         VK_IMAGE_TYPE_2D,                                                                                                                               // VkImageType                          imageType;
1533                         m_depthStencilFormat,                                                                                                                   // VkFormat                                     format;
1534                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                                 // VkExtent3D                           extent;
1535                         1u,                                                                                                                                                             // deUint32                                     mipLevels;
1536                         1u,                                                                                                                                                             // deUint32                                     arrayLayers;
1537                         m_multisampleStateParams.rasterizationSamples,                                                                  // VkSampleCountFlagBits        samples;
1538                         VK_IMAGE_TILING_OPTIMAL,                                                                                                                // VkImageTiling                        tiling;
1539                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,                                                                    // VkImageUsageFlags            usage;
1540                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                              // VkSharingMode                        sharingMode;
1541                         1u,                                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
1542                         &queueFamilyIndex,                                                                                                                              // const deUint32*                      pQueueFamilyIndices;
1543                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                               // VkImageLayout                        initialLayout;
1544                 };
1545
1546                 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
1547
1548                 // Allocate and bind depth/stencil image memory
1549                 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
1550                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
1551         }
1552
1553         // Create color attachment view
1554         {
1555                 const VkImageViewCreateInfo colorAttachmentViewParams =
1556                 {
1557                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
1558                         DE_NULL,                                                                                // const void*                          pNext;
1559                         0u,                                                                                             // VkImageViewCreateFlags       flags;
1560                         *m_colorImage,                                                                  // VkImage                                      image;
1561                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
1562                         m_colorFormat,                                                                  // VkFormat                                     format;
1563                         componentMappingRGBA,                                                   // VkComponentMapping           components;
1564                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
1565                 };
1566
1567                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
1568         }
1569
1570         // Create resolve attachment view
1571         {
1572                 const VkImageViewCreateInfo resolveAttachmentViewParams =
1573                 {
1574                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
1575                         DE_NULL,                                                                                // const void*                          pNext;
1576                         0u,                                                                                             // VkImageViewCreateFlags       flags;
1577                         *m_resolveImage,                                                                // VkImage                                      image;
1578                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
1579                         m_colorFormat,                                                                  // VkFormat                                     format;
1580                         componentMappingRGBA,                                                   // VkComponentMapping           components;
1581                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
1582                 };
1583
1584                 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
1585         }
1586
1587         VkImageAspectFlags      depthStencilAttachmentAspect    = (VkImageAspectFlagBits)0;
1588         const deUint32          numUsedAttachments                              = (m_useDepth || m_useStencil ? 3u : 2u);
1589
1590         // Create depth/stencil attachment view
1591         if (m_useDepth || m_useStencil)
1592         {
1593                 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
1594
1595                 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
1596                 {
1597                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
1598                         DE_NULL,                                                                                        // const void*                          pNext;
1599                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
1600                         *m_depthStencilImage,                                                           // VkImage                                      image;
1601                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
1602                         m_depthStencilFormat,                                                           // VkFormat                                     format;
1603                         componentMappingRGBA,                                                           // VkComponentMapping           components;
1604                         { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }        // VkImageSubresourceRange      subresourceRange;
1605                 };
1606
1607                 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
1608         }
1609
1610         // Create render pass
1611         {
1612                 const VkAttachmentDescription attachmentDescriptions[3] =
1613                 {
1614                         {
1615                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
1616                                 m_colorFormat,                                                                          // VkFormat                                                     format;
1617                                 m_multisampleStateParams.rasterizationSamples,          // VkSampleCountFlagBits                        samples;
1618                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
1619                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
1620                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
1621                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
1622                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
1623                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
1624                         },
1625                         {
1626                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
1627                                 m_colorFormat,                                                                          // VkFormat                                                     format;
1628                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
1629                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
1630                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
1631                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
1632                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
1633                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
1634                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
1635                         },
1636                         {
1637                                 0u,                                                                                                                                                                     // VkAttachmentDescriptionFlags         flags;
1638                                 m_depthStencilFormat,                                                                                                                           // VkFormat                                                     format;
1639                                 m_multisampleStateParams.rasterizationSamples,                                                                          // VkSampleCountFlagBits                        samples;
1640                                 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),           // VkAttachmentLoadOp                           loadOp;
1641                                 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),         // VkAttachmentStoreOp                          storeOp;
1642                                 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),         // VkAttachmentStoreOp                          stencilLoadOp;
1643                                 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),       // VkAttachmentStoreOp                          stencilStoreOp;
1644                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                                        initialLayout;
1645                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL                                                                        // VkImageLayout                                        finalLayout;
1646                         },
1647                 };
1648
1649                 const VkAttachmentReference colorAttachmentReference =
1650                 {
1651                         0u,                                                                                                     // deUint32                     attachment;
1652                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1653                 };
1654
1655                 const VkAttachmentReference resolveAttachmentReference =
1656                 {
1657                         1u,                                                                                                     // deUint32                     attachment;
1658                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
1659                 };
1660
1661                 const VkAttachmentReference depthStencilAttachmentReference =
1662                 {
1663                         2u,                                                                                                     // deUint32                     attachment;
1664                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
1665                 };
1666
1667                 const VkSubpassDescription subpassDescription =
1668                 {
1669                         0u,                                                                                                                                                     // VkSubpassDescriptionFlags    flags;
1670                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                                                                        // VkPipelineBindPoint                  pipelineBindPoint;
1671                         0u,                                                                                                                                                     // deUint32                                             inputAttachmentCount;
1672                         DE_NULL,                                                                                                                                        // const VkAttachmentReference* pInputAttachments;
1673                         1u,                                                                                                                                                     // deUint32                                             colorAttachmentCount;
1674                         &colorAttachmentReference,                                                                                                      // const VkAttachmentReference* pColorAttachments;
1675                         &resolveAttachmentReference,                                                                                            // const VkAttachmentReference* pResolveAttachments;
1676                         (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),      // const VkAttachmentReference* pDepthStencilAttachment;
1677                         0u,                                                                                                                                                     // deUint32                                             preserveAttachmentCount;
1678                         DE_NULL                                                                                                                                         // const VkAttachmentReference* pPreserveAttachments;
1679                 };
1680
1681                 const VkRenderPassCreateInfo renderPassParams =
1682                 {
1683                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
1684                         DE_NULL,                                                                                        // const void*                                          pNext;
1685                         0u,                                                                                                     // VkRenderPassCreateFlags                      flags;
1686                         numUsedAttachments,                                                                     // deUint32                                                     attachmentCount;
1687                         attachmentDescriptions,                                                         // const VkAttachmentDescription*       pAttachments;
1688                         1u,                                                                                                     // deUint32                                                     subpassCount;
1689                         &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
1690                         0u,                                                                                                     // deUint32                                                     dependencyCount;
1691                         DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
1692                 };
1693
1694                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1695         }
1696
1697         // Create framebuffer
1698         {
1699                 const VkImageView attachments[3] =
1700                 {
1701                         *m_colorAttachmentView,
1702                         *m_resolveAttachmentView,
1703                         *m_depthStencilAttachmentView
1704                 };
1705
1706                 const VkFramebufferCreateInfo framebufferParams =
1707                 {
1708                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                              sType;
1709                         DE_NULL,                                                                                        // const void*                                  pNext;
1710                         0u,                                                                                                     // VkFramebufferCreateFlags             flags;
1711                         *m_renderPass,                                                                          // VkRenderPass                                 renderPass;
1712                         numUsedAttachments,                                                                     // deUint32                                             attachmentCount;
1713                         attachments,                                                                            // const VkImageView*                   pAttachments;
1714                         (deUint32)m_renderSize.x(),                                                     // deUint32                                             width;
1715                         (deUint32)m_renderSize.y(),                                                     // deUint32                                             height;
1716                         1u                                                                                                      // deUint32                                             layers;
1717                 };
1718
1719                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1720         }
1721
1722         // Create pipeline layout
1723         {
1724                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1725                 {
1726                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
1727                         DE_NULL,                                                                                        // const void*                                          pNext;
1728                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
1729                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
1730                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
1731                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
1732                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
1733                 };
1734
1735                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1736         }
1737
1738         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1739         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1740
1741         // Create pipeline
1742         {
1743                 const VkPipelineShaderStageCreateInfo shaderStageParams[2] =
1744                 {
1745                         {
1746                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1747                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1748                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
1749                                 VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
1750                                 *m_vertexShaderModule,                                                                          // VkShaderModule                                               module;
1751                                 "main",                                                                                                         // const char*                                                  pName;
1752                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1753                         },
1754                         {
1755                                 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
1756                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
1757                                 0u,                                                                                                                     // VkPipelineShaderStageCreateFlags             flags;
1758                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
1759                                 *m_fragmentShaderModule,                                                                        // VkShaderModule                                               module;
1760                                 "main",                                                                                                         // const char*                                                  pName;
1761                                 DE_NULL                                                                                                         // const VkSpecializationInfo*                  pSpecializationInfo;
1762                         }
1763                 };
1764
1765                 const VkVertexInputBindingDescription vertexInputBindingDescription =
1766                 {
1767                         0u,                                                                     // deUint32                             binding;
1768                         sizeof(Vertex4RGBA),                            // deUint32                             stride;
1769                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
1770                 };
1771
1772                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1773                 {
1774                         {
1775                                 0u,                                                                     // deUint32     location;
1776                                 0u,                                                                     // deUint32     binding;
1777                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
1778                                 0u                                                                      // deUint32     offset;
1779                         },
1780                         {
1781                                 1u,                                                                     // deUint32     location;
1782                                 0u,                                                                     // deUint32     binding;
1783                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
1784                                 DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32     offset;
1785                         }
1786                 };
1787
1788                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1789                 {
1790                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
1791                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1792                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
1793                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
1794                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
1795                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
1796                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
1797                 };
1798
1799                 // Topology is set before the pipeline creation.
1800                 VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
1801                 {
1802                         VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                                                      sType;
1803                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1804                         0u,                                                                                                                             // VkPipelineInputAssemblyStateCreateFlags      flags;
1805                         VK_PRIMITIVE_TOPOLOGY_LAST,                                                                             // VkPrimitiveTopology                                          topology;
1806                         false                                                                                                                   // VkBool32                                                                     primitiveRestartEnable;
1807                 };
1808
1809                 const VkViewport viewport =
1810                 {
1811                         0.0f,                                           // float        x;
1812                         0.0f,                                           // float        y;
1813                         (float)m_renderSize.x(),        // float        width;
1814                         (float)m_renderSize.y(),        // float        height;
1815                         0.0f,                                           // float        minDepth;
1816                         1.0f                                            // float        maxDepth;
1817                 };
1818
1819                 const VkRect2D scissor =
1820                 {
1821                         { 0, 0 },                                                                                                       // VkOffset2D  offset;
1822                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }      // VkExtent2D  extent;
1823                 };
1824
1825                 const VkPipelineViewportStateCreateInfo viewportStateParams =
1826                 {
1827                         VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                                              sType;
1828                         DE_NULL,                                                                                                                // const void*                                                  pNext;
1829                         0u,                                                                                                                             // VkPipelineViewportStateCreateFlags   flags;
1830                         1u,                                                                                                                             // deUint32                                                             viewportCount;
1831                         &viewport,                                                                                                              // const VkViewport*                                    pViewports;
1832                         1u,                                                                                                                             // deUint32                                                             scissorCount;
1833                         &scissor                                                                                                                // const VkRect2D*                                              pScissors;
1834                 };
1835
1836                 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
1837                 {
1838                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
1839                         DE_NULL,                                                                                                                // const void*                                                          pNext;
1840                         0u,                                                                                                                             // VkPipelineRasterizationStateCreateFlags      flags;
1841                         false,                                                                                                                  // VkBool32                                                                     depthClampEnable;
1842                         false,                                                                                                                  // VkBool32                                                                     rasterizerDiscardEnable;
1843                         VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
1844                         VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
1845                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
1846                         VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
1847                         0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
1848                         0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
1849                         0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
1850                         1.0f                                                                                                                    // float                                                                        lineWidth;
1851                 };
1852
1853                 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1854                 {
1855                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
1856                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
1857                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
1858                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
1859                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
1860                         1u,                                                                                                                     // deUint32                                                                             attachmentCount;
1861                         &m_colorBlendState,                                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
1862                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
1863                 };
1864
1865                 const VkStencilOpState stencilOpState =
1866                 {
1867                         VK_STENCIL_OP_KEEP,                                             // VkStencilOp  failOp;
1868                         VK_STENCIL_OP_REPLACE,                                  // VkStencilOp  passOp;
1869                         VK_STENCIL_OP_KEEP,                                             // VkStencilOp  depthFailOp;
1870                         VK_COMPARE_OP_GREATER,                                  // VkCompareOp  compareOp;
1871                         1u,                                                                             // deUint32             compareMask;
1872                         1u,                                                                             // deUint32             writeMask;
1873                         1u,                                                                             // deUint32             reference;
1874                 };
1875
1876                 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
1877                 {
1878                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
1879                         DE_NULL,                                                                                                        // const void*                                                          pNext;
1880                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
1881                         m_useDepth,                                                                                                     // VkBool32                                                                     depthTestEnable;
1882                         m_useDepth,                                                                                                     // VkBool32                                                                     depthWriteEnable;
1883                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
1884                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
1885                         m_useStencil,                                                                                           // VkBool32                                                                     stencilTestEnable;
1886                         stencilOpState,                                                                                         // VkStencilOpState     front;
1887                         stencilOpState,                                                                                         // VkStencilOpState     back;
1888                         0.0f,                                                                                                           // float                        minDepthBounds;
1889                         1.0f,                                                                                                           // float                        maxDepthBounds;
1890                 };
1891
1892                 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
1893                 {
1894                         VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
1895                         DE_NULL,                                                                                        // const void*                                                                          pNext;
1896                         0u,                                                                                                     // VkPipelineCreateFlags                                                        flags;
1897                         2u,                                                                                                     // deUint32                                                                                     stageCount;
1898                         shaderStageParams,                                                                      // const VkPipelineShaderStageCreateInfo*                       pStages;
1899                         &vertexInputStateParams,                                                        // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
1900                         &inputAssemblyStateParams,                                                      // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
1901                         DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
1902                         &viewportStateParams,                                                           // const VkPipelineViewportStateCreateInfo*                     pViewportState;
1903                         &rasterStateParams,                                                                     // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
1904                         &m_multisampleStateParams,                                                      // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
1905                         &depthStencilStateParams,                                                       // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
1906                         &colorBlendStateParams,                                                         // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
1907                         (const VkPipelineDynamicStateCreateInfo*)DE_NULL,       // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
1908                         *m_pipelineLayout,                                                                      // VkPipelineLayout                                                                     layout;
1909                         *m_renderPass,                                                                          // VkRenderPass                                                                         renderPass;
1910                         0u,                                                                                                     // deUint32                                                                                     subpass;
1911                         0u,                                                                                                     // VkPipeline                                                                           basePipelineHandle;
1912                         0u                                                                                                      // deInt32                                                                                      basePipelineIndex;
1913                 };
1914
1915                 for (deUint32 i = 0u; i < numTopologies; ++i)
1916                 {
1917                         inputAssemblyStateParams.topology = pTopology[i];
1918                         m_graphicsPipelines.push_back(VkPipelineSp(new Unique<VkPipeline>(createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams))));
1919                 }
1920         }
1921
1922         // Create vertex buffer
1923         {
1924                 const VkBufferCreateInfo vertexBufferParams =
1925                 {
1926                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
1927                         DE_NULL,                                                                        // const void*                  pNext;
1928                         0u,                                                                                     // VkBufferCreateFlags  flags;
1929                         1024u,                                                                          // VkDeviceSize                 size;
1930                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
1931                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
1932                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
1933                         &queueFamilyIndex                                                       // const deUint32*              pQueueFamilyIndices;
1934                 };
1935
1936                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
1937                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
1938
1939                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1940
1941                 // Load vertices into vertex buffer
1942                 {
1943                         Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
1944                         for (deUint32 i = 0u; i < numTopologies; ++i)
1945                         {
1946                                 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
1947                                 pDst += pVertices[i].size();
1948                         }
1949                 }
1950                 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
1951         }
1952
1953         // Create command pool
1954         {
1955                 const VkCommandPoolCreateInfo cmdPoolParams =
1956                 {
1957                         VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,             // VkStructureType                              sType;
1958                         DE_NULL,                                                                                // const void*                                  pNext;
1959                         VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,                   // VkCommandPoolCreateFlags             flags;
1960                         queueFamilyIndex,                                                               // deUint32                                             queueFamilyIndex;
1961                 };
1962
1963                 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
1964         }
1965
1966         // Create command buffer
1967         {
1968                 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
1969                 {
1970                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType                      sType;
1971                         DE_NULL,                                                                                // const void*                          pNext;
1972                         *m_cmdPool,                                                                             // VkCommandPool                        commandPool;
1973                         VK_COMMAND_BUFFER_LEVEL_PRIMARY,                                // VkCommandBufferLevel level;
1974                         1u                                                                                              // deUint32                             bufferCount;
1975                 };
1976
1977                 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1978                 {
1979                         VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,    // VkStructureType                                      sType;
1980                         DE_NULL,                                                                                // const void*                                          pNext;
1981                         0u,                                                                                             // VkCommandBufferUsageFlags            flags;
1982                         (const VkCommandBufferInheritanceInfo*)DE_NULL,
1983                 };
1984
1985                 VkClearValue colorClearValue;
1986                 colorClearValue.color.float32[0] = 0.0f;
1987                 colorClearValue.color.float32[1] = 0.0f;
1988                 colorClearValue.color.float32[2] = 0.0f;
1989                 colorClearValue.color.float32[3] = 0.0f;
1990
1991                 VkClearValue depthStencilClearValue;
1992                 depthStencilClearValue.depthStencil.depth = 1.0f;
1993                 depthStencilClearValue.depthStencil.stencil = 0u;
1994
1995                 const VkClearValue clearValues[3] =
1996                 {
1997                         colorClearValue,
1998                         colorClearValue,
1999                         depthStencilClearValue
2000                 };
2001
2002                 const VkRenderPassBeginInfo renderPassBeginInfo =
2003                 {
2004                         VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,                               // VkStructureType              sType;
2005                         DE_NULL,                                                                                                // const void*                  pNext;
2006                         *m_renderPass,                                                                                  // VkRenderPass                 renderPass;
2007                         *m_framebuffer,                                                                                 // VkFramebuffer                framebuffer;
2008                         {
2009                                 { 0, 0 },
2010                                 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
2011                         },                                                                                                              // VkRect2D                             renderArea;
2012                         numUsedAttachments,                                                                             // deUint32                             clearValueCount;
2013                         clearValues                                                                                             // const VkClearValue*  pClearValues;
2014                 };
2015
2016                 const VkImageMemoryBarrier imageLayoutBarriers[] =
2017                 {
2018                         // color attachment image
2019                         {
2020                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
2021                                 DE_NULL,                                                                                // const void*                          pNext;
2022                                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
2023                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
2024                                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
2025                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        newLayout;
2026                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
2027                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
2028                                 *m_colorImage,                                                                  // VkImage                                      image;
2029                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
2030                         },
2031                         // resolve attachment image
2032                         {
2033                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
2034                                 DE_NULL,                                                                                // const void*                          pNext;
2035                                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
2036                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
2037                                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
2038                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        newLayout;
2039                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
2040                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
2041                                 *m_resolveImage,                                                                // VkImage                                      image;
2042                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
2043                         },
2044                         // depth/stencil attachment image
2045                         {
2046                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
2047                                 DE_NULL,                                                                                        // const void*                          pNext;
2048                                 0u,                                                                                                     // VkAccessFlags                        srcAccessMask;
2049                                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
2050                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
2051                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
2052                                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
2053                                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     dstQueueFamilyIndex;
2054                                 *m_depthStencilImage,                                                           // VkImage                                      image;
2055                                 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },       // VkImageSubresourceRange      subresourceRange;
2056                         },
2057                 };
2058
2059                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
2060
2061                 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
2062
2063                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, (VkDependencyFlags)0,
2064                         0u, DE_NULL, 0u, DE_NULL, numUsedAttachments, imageLayoutBarriers);
2065
2066                 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
2067
2068                 VkDeviceSize vertexBufferOffset = 0u;
2069
2070                 for (deUint32 i = 0u; i < numTopologies; ++i)
2071                 {
2072                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, **m_graphicsPipelines[i]);
2073                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
2074                         vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
2075
2076                         vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
2077                 }
2078
2079                 vk.cmdEndRenderPass(*m_cmdBuffer);
2080
2081                 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
2082         }
2083
2084         // Create fence
2085         {
2086                 const VkFenceCreateInfo fenceParams =
2087                 {
2088                         VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,    // VkStructureType              sType;
2089                         DE_NULL,                                                                // const void*                  pNext;
2090                         0u                                                                              // VkFenceCreateFlags   flags;
2091                 };
2092
2093                 m_fence = createFence(vk, vkDevice, &fenceParams);
2094         }
2095 }
2096
2097 MultisampleRenderer::~MultisampleRenderer (void)
2098 {
2099 }
2100
2101 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
2102 {
2103         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
2104         const VkDevice                          vkDevice                        = m_context.getDevice();
2105         const VkQueue                           queue                           = m_context.getUniversalQueue();
2106         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
2107         SimpleAllocator                         allocator                       (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
2108         const VkSubmitInfo                      submitInfo      =
2109         {
2110                 VK_STRUCTURE_TYPE_SUBMIT_INFO,  // VkStructureType                      sType;
2111                 DE_NULL,                                                // const void*                          pNext;
2112                 0u,                                                             // deUint32                                     waitSemaphoreCount;
2113                 DE_NULL,                                                // const VkSemaphore*           pWaitSemaphores;
2114                 (const VkPipelineStageFlags*)DE_NULL,
2115                 1u,                                                             // deUint32                                     commandBufferCount;
2116                 &m_cmdBuffer.get(),                             // const VkCommandBuffer*       pCommandBuffers;
2117                 0u,                                                             // deUint32                                     signalSemaphoreCount;
2118                 DE_NULL                                                 // const VkSemaphore*           pSignalSemaphores;
2119         };
2120
2121         VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
2122         VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
2123         VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity*/));
2124
2125         return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
2126 }
2127
2128 } // anonymous
2129
2130 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx)
2131 {
2132         const VkSampleCountFlagBits samples[] =
2133         {
2134                 VK_SAMPLE_COUNT_2_BIT,
2135                 VK_SAMPLE_COUNT_4_BIT,
2136                 VK_SAMPLE_COUNT_8_BIT,
2137                 VK_SAMPLE_COUNT_16_BIT,
2138                 VK_SAMPLE_COUNT_32_BIT,
2139                 VK_SAMPLE_COUNT_64_BIT
2140         };
2141
2142         de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, "multisample", ""));
2143
2144         // Rasterization samples tests
2145         {
2146                 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
2147
2148                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2149                 {
2150                         std::ostringstream caseName;
2151                         caseName << "samples_" << samples[samplesNdx];
2152
2153                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2154
2155                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",  samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2156                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",              samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE));
2157                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",             samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT));
2158
2159                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",                       samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT));
2160                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",                     samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_STENCIL_BIT));
2161                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",       samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT));
2162
2163                         rasterizationSamplesTests->addChild(samplesTests.release());
2164                 }
2165
2166                 multisampleTests->addChild(rasterizationSamplesTests.release());
2167         }
2168
2169         // Raster samples consistency check
2170         {
2171                 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests(new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
2172
2173                 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
2174                                                                         "unique_colors_check",
2175                                                                         "",
2176                                                                         initMultisamplePrograms,
2177                                                                         testRasterSamplesConsistency,
2178                                                                         GEOMETRY_TYPE_OPAQUE_TRIANGLE);
2179
2180                 multisampleTests->addChild(rasterSamplesConsistencyTests.release());
2181         }
2182
2183         // minSampleShading tests
2184         {
2185                 struct TestConfig
2186                 {
2187                         const char*     name;
2188                         float           minSampleShading;
2189                 };
2190
2191                 const TestConfig testConfigs[] =
2192                 {
2193                         { "min_0_0",    0.0f },
2194                         { "min_0_25",   0.25f },
2195                         { "min_0_5",    0.5f },
2196                         { "min_0_75",   0.75f },
2197                         { "min_1_0",    1.0f }
2198                 };
2199
2200                 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
2201
2202                 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
2203                 {
2204                         const TestConfig&                               testConfig                              = testConfigs[configNdx];
2205                         de::MovePtr<tcu::TestCaseGroup> minShadingValueTests    (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
2206
2207                         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2208                         {
2209                                 std::ostringstream caseName;
2210                                 caseName << "samples_" << samples[samplesNdx];
2211
2212                                 de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2213
2214                                 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2215                                 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE));
2216                                 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT));
2217
2218                                 minShadingValueTests->addChild(samplesTests.release());
2219                         }
2220
2221                         minSampleShadingTests->addChild(minShadingValueTests.release());
2222                 }
2223
2224                 multisampleTests->addChild(minSampleShadingTests.release());
2225         }
2226
2227         // pSampleMask tests
2228         {
2229                 struct TestConfig
2230                 {
2231                         const char*             name;
2232                         const char*             description;
2233                         VkSampleMask    sampleMask;
2234                 };
2235
2236                 const TestConfig testConfigs[] =
2237                 {
2238                         { "mask_all_on",        "All mask bits are off",                        0x0 },
2239                         { "mask_all_off",       "All mask bits are on",                         0xFFFFFFFF },
2240                         { "mask_one",           "All mask elements are 0x1",            0x1},
2241                         { "mask_random",        "All mask elements are 0xAAAAAAAA",     0xAAAAAAAA },
2242                 };
2243
2244                 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
2245
2246                 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
2247                 {
2248                         const TestConfig&                               testConfig                              = testConfigs[configNdx];
2249                         de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests    (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
2250
2251                         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2252                         {
2253                                 std::ostringstream caseName;
2254                                 caseName << "samples_" << samples[samplesNdx];
2255
2256                                 const deUint32                                  sampleMaskCount = samples[samplesNdx] / 32;
2257                                 de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2258
2259                                 std::vector<VkSampleMask> mask;
2260                                 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
2261                                         mask.push_back(testConfig.sampleMask);
2262
2263                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE));
2264                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE));
2265                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT));
2266
2267                                 sampleMaskValueTests->addChild(samplesTests.release());
2268                         }
2269
2270                         sampleMaskTests->addChild(sampleMaskValueTests.release());
2271                 }
2272
2273                 multisampleTests->addChild(sampleMaskTests.release());
2274
2275         }
2276
2277         // AlphaToOne tests
2278         {
2279                 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
2280
2281                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2282                 {
2283                         std::ostringstream caseName;
2284                         caseName << "samples_" << samples[samplesNdx];
2285
2286                         alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", samples[samplesNdx]));
2287                 }
2288
2289                 multisampleTests->addChild(alphaToOneTests.release());
2290         }
2291
2292         // AlphaToCoverageEnable tests
2293         {
2294                 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
2295
2296                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2297                 {
2298                         std::ostringstream caseName;
2299                         caseName << "samples_" << samples[samplesNdx];
2300
2301                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
2302
2303                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD));
2304                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD));
2305                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD));
2306
2307                         alphaToCoverageTests->addChild(samplesTests.release());
2308                 }
2309                 multisampleTests->addChild(alphaToCoverageTests.release());
2310         }
2311
2312         // Sampling from a multisampled image texture (texelFetch)
2313         {
2314                 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx));
2315         }
2316
2317         // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
2318         {
2319                 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx));
2320         }
2321
2322         return multisampleTests.release();
2323 }
2324
2325 } // pipeline
2326 } // vkt