29fe56f17762e53a6b970203a780dbca406c5260
[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  * Copyright (c) 2017 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Multisample Tests
24  *//*--------------------------------------------------------------------*/
25
26 #include "vktPipelineMultisampleTests.hpp"
27 #include "vktPipelineMultisampleImageTests.hpp"
28 #include "vktPipelineMultisampleSampleLocationsExtTests.hpp"
29 #include "vktPipelineMultisampleMixedAttachmentSamplesTests.hpp"
30 #include "vktPipelineMultisampleResolveRenderAreaTests.hpp"
31 #include "vktPipelineMultisampleShaderFragmentMaskTests.hpp"
32 #include "vktPipelineMultisampledRenderToSingleSampledTests.hpp"
33 #include "vktPipelineClearUtil.hpp"
34 #include "vktPipelineImageUtil.hpp"
35 #include "vktPipelineVertexUtil.hpp"
36 #include "vktPipelineReferenceRenderer.hpp"
37 #include "vktTestCase.hpp"
38 #include "vktTestCaseUtil.hpp"
39 #include "vkImageUtil.hpp"
40 #include "vkMemUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkQueryUtil.hpp"
43 #include "vkRef.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vkCmdUtil.hpp"
46 #include "vkTypeUtil.hpp"
47 #include "vkObjUtil.hpp"
48 #include "vkBufferWithMemory.hpp"
49 #include "vkImageWithMemory.hpp"
50 #include "vkBuilderUtil.hpp"
51 #include "vkBarrierUtil.hpp"
52 #include "tcuImageCompare.hpp"
53 #include "tcuTestLog.hpp"
54 #include "deUniquePtr.hpp"
55 #include "deSharedPtr.hpp"
56 #include "deStringUtil.hpp"
57 #include "deMemory.h"
58
59 #include <sstream>
60 #include <vector>
61 #include <map>
62 #include <memory>
63 #include <algorithm>
64 #include <set>
65 #include <array>
66 #include <utility>
67
68 namespace vkt
69 {
70 namespace pipeline
71 {
72
73 using namespace vk;
74
75 namespace
76 {
77 enum GeometryType
78 {
79         GEOMETRY_TYPE_OPAQUE_TRIANGLE,
80         GEOMETRY_TYPE_OPAQUE_LINE,
81         GEOMETRY_TYPE_OPAQUE_POINT,
82         GEOMETRY_TYPE_OPAQUE_QUAD,
83         GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH,        //!< placed at z = 0.5
84         GEOMETRY_TYPE_TRANSLUCENT_QUAD,
85         GEOMETRY_TYPE_INVISIBLE_TRIANGLE,
86         GEOMETRY_TYPE_INVISIBLE_QUAD,
87         GEOMETRY_TYPE_GRADIENT_QUAD
88 };
89
90 enum TestModeBits
91 {
92         TEST_MODE_DEPTH_BIT             = 1u,
93         TEST_MODE_STENCIL_BIT   = 2u,
94 };
95 typedef deUint32 TestModeFlags;
96
97 enum RenderType
98 {
99         // resolve multisample rendering to single sampled image
100         RENDER_TYPE_RESOLVE                             = 0u,
101
102         // copy samples to an array of single sampled images
103         RENDER_TYPE_COPY_SAMPLES                = 1u,
104
105         // render first with only depth/stencil and then with color + depth/stencil
106         RENDER_TYPE_DEPTHSTENCIL_ONLY   = 2u,
107
108         // render using color attachment at location 1 and location 0 set as unused
109         RENDER_TYPE_UNUSED_ATTACHMENT   = 3u,
110
111         // render using color attachment with single sample, required by alpha_to_one tests.
112         RENDER_TYPE_SINGLE_SAMPLE               = 4u
113 };
114
115 enum ImageBackingMode
116 {
117         IMAGE_BACKING_MODE_REGULAR      = 0u,
118         IMAGE_BACKING_MODE_SPARSE
119 };
120
121 struct MultisampleTestParams
122 {
123         PipelineConstructionType        pipelineConstructionType;
124         GeometryType                            geometryType;
125         float                                           pointSize;
126         ImageBackingMode                        backingMode;
127         bool                                            useFragmentShadingRate;
128 };
129
130 void                                                                    initMultisamplePrograms                         (SourceCollections& sources, MultisampleTestParams params);
131 bool                                                                    isSupportedSampleCount                          (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples);
132 bool                                                                    isSupportedDepthStencilFormat           (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format);
133 VkPipelineColorBlendAttachmentState             getDefaultColorBlendAttachmentState     (void);
134 deUint32                                                                getUniqueColorsCount                            (const tcu::ConstPixelBufferAccess& image);
135 VkImageAspectFlags                                              getImageAspectFlags                                     (const VkFormat format);
136 VkPrimitiveTopology                                             getPrimitiveTopology                            (const GeometryType geometryType);
137 std::vector<Vertex4RGBA>                                generateVertices                                        (const GeometryType geometryType);
138 VkFormat                                                                findSupportedDepthStencilFormat         (Context& context, const bool useDepth, const bool useStencil);
139
140 class MultisampleTest : public vkt::TestCase
141 {
142 public:
143
144                                                                                                 MultisampleTest                                         (tcu::TestContext&                                                              testContext,
145                                                                                                                                                                          const std::string&                                                             name,
146                                                                                                                                                                          const std::string&                                                             description,
147                                                                                                                                                                          PipelineConstructionType                                               pipelineConstructionType,
148                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
149                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
150                                                                                                                                                                          GeometryType                                                                   geometryType,
151                                                                                                                                                                          float                                                                                  pointSize,
152                                                                                                                                                                          ImageBackingMode                                                               backingMode,
153                                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
154         virtual                                                                         ~MultisampleTest                                        (void) {}
155
156         virtual void                                                            initPrograms                                            (SourceCollections& programCollection) const;
157         virtual TestInstance*                                           createInstance                                          (Context& context) const;
158         virtual void                                                            checkSupport                                            (Context& context) const;
159
160 protected:
161         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
162                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
163                                                                                                                                                                          float                                                                                  pointSize,
164                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
165                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
166                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const = 0;
167
168         const PipelineConstructionType                          m_pipelineConstructionType;
169         VkPipelineMultisampleStateCreateInfo            m_multisampleStateParams;
170         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
171         const GeometryType                                                      m_geometryType;
172         const float                                                                     m_pointSize;
173         const ImageBackingMode                                          m_backingMode;
174         std::vector<VkSampleMask>                                       m_sampleMask;
175         bool                                                                            m_useFragmentShadingRate;
176 };
177
178 class RasterizationSamplesTest : public MultisampleTest
179 {
180 public:
181                                                                                                 RasterizationSamplesTest                        (tcu::TestContext&                      testContext,
182                                                                                                                                                                          const std::string&                     name,
183                                                                                                                                                                          const std::string&                     description,
184                                                                                                                                                                          PipelineConstructionType       pipelineConstructionType,
185                                                                                                                                                                          VkSampleCountFlagBits          rasterizationSamples,
186                                                                                                                                                                          GeometryType                           geometryType,
187                                                                                                                                                                          float                                          pointSize,
188                                                                                                                                                                          ImageBackingMode                       backingMode,
189                                                                                                                                                                          TestModeFlags                          modeFlags,
190                                                                                                                                                                          const bool                                     useFragmentShadingRate);
191         virtual                                                                         ~RasterizationSamplesTest                       (void) {}
192
193 protected:
194         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
195                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
196                                                                                                                                                                          float                                                                                  pointSize,
197                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
198                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
199                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
200
201         static VkPipelineMultisampleStateCreateInfo     getRasterizationSamplesStateParams      (VkSampleCountFlagBits rasterizationSamples);
202
203         const ImageBackingMode                                          m_backingMode;
204         const TestModeFlags                                                     m_modeFlags;
205 };
206
207 class MinSampleShadingTest : public MultisampleTest
208 {
209 public:
210                                                                                                 MinSampleShadingTest                            (tcu::TestContext&                              testContext,
211                                                                                                                                                                          const std::string&                             name,
212                                                                                                                                                                          const std::string&                             description,
213                                                                                                                                                                          const PipelineConstructionType pipelineConstructionType,
214                                                                                                                                                                          VkSampleCountFlagBits                  rasterizationSamples,
215                                                                                                                                                                          float                                                  minSampleShading,
216                                                                                                                                                                          GeometryType                                   geometryType,
217                                                                                                                                                                          float                                                  pointSize,
218                                                                                                                                                                          ImageBackingMode                               backingMode,
219                                                                                                                                                                          const bool                                             minSampleShadingEnabled,
220                                                                                                                                                                          const bool                                             useFragmentShadingRate);
221         virtual                                                                         ~MinSampleShadingTest                           (void) {}
222
223 protected:
224         virtual void                                                            initPrograms                                            (SourceCollections& programCollection) const;
225         virtual void                                                            checkSupport                                            (Context& context) const;
226         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
227                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
228                                                                                                                                                                          float                                                                                  pointSize,
229                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
230                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
231                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
232
233         static VkPipelineMultisampleStateCreateInfo     getMinSampleShadingStateParams          (VkSampleCountFlagBits  rasterizationSamples,
234                                                                                                                                                                          float                                  minSampleShading,
235                                                                                                                                                                          bool                                   minSampleShadingEnabled);
236
237         const float                                                                     m_pointSize;
238         const ImageBackingMode                                          m_backingMode;
239         const bool                                                                      m_minSampleShadingEnabled;
240 };
241
242 class SampleMaskTest : public MultisampleTest
243 {
244 public:
245                                                                                                 SampleMaskTest                                          (tcu::TestContext&                                      testContext,
246                                                                                                                                                                          const std::string&                                     name,
247                                                                                                                                                                          const std::string&                                     description,
248                                                                                                                                                                          const PipelineConstructionType         pipelineConstructionType,
249                                                                                                                                                                          VkSampleCountFlagBits                          rasterizationSamples,
250                                                                                                                                                                          const std::vector<VkSampleMask>&       sampleMask,
251                                                                                                                                                                          GeometryType                                           geometryType,
252                                                                                                                                                                          float                                                          pointSize,
253                                                                                                                                                                          ImageBackingMode                                       backingMode,
254                                                                                                                                                                          const bool                                                     useFragmentShadingRate);
255
256         virtual                                                                         ~SampleMaskTest                                         (void) {}
257
258 protected:
259         virtual TestInstance*                                           createMultisampleTestInstance           (Context&                                                                               context,
260                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
261                                                                                                                                                                          float                                                                                  pointSize,
262                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
263                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
264                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
265
266         static VkPipelineMultisampleStateCreateInfo     getSampleMaskStateParams                        (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask);
267
268         const ImageBackingMode                                          m_backingMode;
269 };
270
271 class AlphaToOneTest : public MultisampleTest
272 {
273 public:
274                                                                                                 AlphaToOneTest                                  (tcu::TestContext&                                      testContext,
275                                                                                                                                                                  const std::string&                                     name,
276                                                                                                                                                                  const std::string&                                     description,
277                                                                                                                                                                  const PipelineConstructionType         pipelineConstructionType,
278                                                                                                                                                                  VkSampleCountFlagBits                          rasterizationSamples,
279                                                                                                                                                                  ImageBackingMode                                       backingMode,
280                                                                                                                                                                  const bool                                                     useFragmentShadingRate);
281
282         virtual                                                                         ~AlphaToOneTest                                 (void) {}
283
284 protected:
285         virtual void                                                            checkSupport                                    (Context& context) const;
286         virtual TestInstance*                                           createMultisampleTestInstance   (Context&                                                                               context,
287                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
288                                                                                                                                                                  float                                                                                  pointSize,
289                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
290                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
291                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
292
293         static VkPipelineMultisampleStateCreateInfo     getAlphaToOneStateParams                (VkSampleCountFlagBits rasterizationSamples);
294         static VkPipelineColorBlendAttachmentState      getAlphaToOneBlendState                 (void);
295
296         const ImageBackingMode                                          m_backingMode;
297 };
298
299 class AlphaToCoverageTest : public MultisampleTest
300 {
301 public:
302                                                                                                 AlphaToCoverageTest                             (tcu::TestContext&                                      testContext,
303                                                                                                                                                                  const std::string&                                     name,
304                                                                                                                                                                  const std::string&                                     description,
305                                                                                                                                                                  const PipelineConstructionType         pipelineConstructionType,
306                                                                                                                                                                  VkSampleCountFlagBits                          rasterizationSamples,
307                                                                                                                                                                  GeometryType                                           geometryType,
308                                                                                                                                                                  ImageBackingMode                                       backingMode,
309                                                                                                                                                                  const bool                                                     useFragmentShadingRate);
310
311         virtual                                                                         ~AlphaToCoverageTest                    (void) {}
312
313 protected:
314         virtual TestInstance*                                           createMultisampleTestInstance   (Context&                                                                               context,
315                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
316                                                                                                                                                                  float                                                                                  pointSize,
317                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
318                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
319                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
320
321         static VkPipelineMultisampleStateCreateInfo     getAlphaToCoverageStateParams   (VkSampleCountFlagBits rasterizationSamples);
322
323         GeometryType                                                            m_geometryType;
324         const ImageBackingMode                                          m_backingMode;
325 };
326
327 class AlphaToCoverageNoColorAttachmentTest : public MultisampleTest
328 {
329 public:
330                                                                                                 AlphaToCoverageNoColorAttachmentTest    (tcu::TestContext&                                      testContext,
331                                                                                                                                                                                  const std::string&                                     name,
332                                                                                                                                                                                  const std::string&                                     description,
333                                                                                                                                                                                  const PipelineConstructionType         pipelineConstructionType,
334                                                                                                                                                                                  VkSampleCountFlagBits                          rasterizationSamples,
335                                                                                                                                                                                  GeometryType                                           geometryType,
336                                                                                                                                                                                  ImageBackingMode                                       backingMode,
337                                                                                                                                                                                  const bool                                                     useFragmentShadingRate);
338
339         virtual                                                                         ~AlphaToCoverageNoColorAttachmentTest   (void) {}
340
341 protected:
342         virtual TestInstance*                                           createMultisampleTestInstance                   (Context&                                                                               context,
343                                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
344                                                                                                                                                                                  float                                                                                  pointSize,
345                                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
346                                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
347                                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
348
349         static VkPipelineMultisampleStateCreateInfo     getStateParams                                                  (VkSampleCountFlagBits rasterizationSamples);
350
351         GeometryType                                                            m_geometryType;
352         const ImageBackingMode                                          m_backingMode;
353 };
354
355 class AlphaToCoverageColorUnusedAttachmentTest : public MultisampleTest
356 {
357 public:
358                                                                                                 AlphaToCoverageColorUnusedAttachmentTest        (tcu::TestContext&                                      testContext,
359                                                                                                                                                                                          const std::string&                                     name,
360                                                                                                                                                                                          const std::string&                                     description,
361                                                                                                                                                                                          const PipelineConstructionType         pipelineConstructionType,
362                                                                                                                                                                                          VkSampleCountFlagBits                          rasterizationSamples,
363                                                                                                                                                                                          GeometryType                                           geometryType,
364                                                                                                                                                                                          ImageBackingMode                                       backingMode,
365                                                                                                                                                                                          const bool                                                     useFragmentShadingRate);
366
367         virtual                                                                         ~AlphaToCoverageColorUnusedAttachmentTest       (void) {}
368
369 protected:
370         virtual void                                                            initPrograms                                                            (SourceCollections& programCollection) const;
371
372         virtual TestInstance*                                           createMultisampleTestInstance                           (Context&                                                                               context,
373                                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
374                                                                                                                                                                                          float                                                                                  pointSize,
375                                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
376                                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
377                                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const;
378
379         static VkPipelineMultisampleStateCreateInfo     getStateParams                                                          (VkSampleCountFlagBits rasterizationSamples);
380
381         GeometryType                                                            m_geometryType;
382         const ImageBackingMode                                          m_backingMode;
383 };
384
385 class SampleMaskWithConservativeTest : public vkt::TestCase
386 {
387         public:
388                                                                                                 SampleMaskWithConservativeTest(tcu::TestContext&                                                        testContext,
389                                                                                                                                                                 const std::string&                                                      name,
390                                                                                                                                                                 const std::string&                                                      description,
391                                                                                                                                                                 const PipelineConstructionType                          pipelineConstructionType,
392                                                                                                                                                                 const VkSampleCountFlagBits                                     rasterizationSamples,
393                                                                                                                                                                 const VkConservativeRasterizationModeEXT        conservativeRasterizationMode,
394                                                                                                                                                                 const bool                                                                      enableMinSampleShading,
395                                                                                                                                                                 const float                                                                     minSampleShading,
396                                                                                                                                                                 const bool                                                                      enableSampleMask,
397                                                                                                                                                                 const VkSampleMask                                                      sampleMask,
398                                                                                                                                                                 const bool                                                                      enablePostDepthCoverage,
399                                                                                                                                                                 const bool                                                                      useFragmentShadingRate);
400
401                                                                                                 ~SampleMaskWithConservativeTest (void) {}
402
403         void                                                                            initPrograms                                    (SourceCollections&             programCollection)      const;
404         TestInstance*                                                           createInstance                                  (Context&                               context)                        const;
405         virtual void                                                            checkSupport                                    (Context&                               context)                        const;
406
407 private:
408         const PipelineConstructionType                          m_pipelineConstructionType;
409         const VkSampleCountFlagBits                                     m_rasterizationSamples;
410         const bool                                                                      m_enableMinSampleShading;
411         float                                                                           m_minSampleShading;
412         const bool                                                                      m_enableSampleMask;
413         const VkSampleMask                                                      m_sampleMask;
414         const VkConservativeRasterizationModeEXT        m_conservativeRasterizationMode;
415         const bool                                                                      m_enablePostDepthCoverage;
416         const RenderType                                                        m_renderType;
417         const bool                                                                      m_useFragmentShadingRate;
418 };
419 #ifndef CTS_USES_VULKANSC
420 class SampleMaskWithDepthTestTest : public vkt::TestCase
421 {
422 public:
423                                                                                                 SampleMaskWithDepthTestTest             (tcu::TestContext&                              testContext,
424                                                                                                                                                                  const std::string&                             name,
425                                                                                                                                                                  const std::string&                             description,
426                                                                                                                                                                  const PipelineConstructionType pipelineConstructionType,
427                                                                                                                                                                  const VkSampleCountFlagBits    rasterizationSamples,
428                                                                                                                                                                  const bool                                             enablePostDepthCoverage,
429                                                                                                                                                                  const bool                                             useFragmentShadingRate);
430
431                                                                                                 ~SampleMaskWithDepthTestTest    (void) {}
432
433         void                                                                            initPrograms                                    (SourceCollections&             programCollection)      const;
434         TestInstance*                                                           createInstance                                  (Context&                               context)                        const;
435         virtual void                                                            checkSupport                                    (Context&                               context)                        const;
436 private:
437         const PipelineConstructionType                          m_pipelineConstructionType;
438         const VkSampleCountFlagBits                                     m_rasterizationSamples;
439         const bool                                                                      m_enablePostDepthCoverage;
440         const bool                                                                      m_useFragmentShadingRate;
441 };
442 #endif // CTS_USES_VULKANSC
443 class MultisampleRenderer
444 {
445 public:
446
447                                                                                                 MultisampleRenderer                     (Context&                                                                               context,
448                                                                                                                                                          PipelineConstructionType                                               pipelineConstructionType,
449                                                                                                                                                          const VkFormat                                                                 colorFormat,
450                                                                                                                                                          const tcu::IVec2&                                                              renderSize,
451                                                                                                                                                          const VkPrimitiveTopology                                              topology,
452                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
453                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
454                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
455                                                                                                                                                          const RenderType                                                               renderType,
456                                                                                                                                                          const ImageBackingMode                                                 backingMode,
457                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
458
459                                                                                                 MultisampleRenderer                     (Context&                                                                               context,
460                                                                                                                                                          PipelineConstructionType                                               pipelineConstructionType,
461                                                                                                                                                          const VkFormat                                                                 colorFormat,
462                                                                                                                                                          const VkFormat                                                                 depthStencilFormat,
463                                                                                                                                                          const tcu::IVec2&                                                              renderSize,
464                                                                                                                                                          const bool                                                                             useDepth,
465                                                                                                                                                          const bool                                                                             useStencil,
466                                                                                                                                                          const deUint32                                                                 numTopologies,
467                                                                                                                                                          const VkPrimitiveTopology*                                             pTopology,
468                                                                                                                                                          const std::vector<Vertex4RGBA>*                                pVertices,
469                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
470                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
471                                                                                                                                                          const RenderType                                                               renderType,
472                                                                                                                                                          const ImageBackingMode                                                 backingMode,
473                                                                                                                                                          const bool                                                                             useFragmentShadingRate,
474                                                                                                                                                          const float                                                                    depthClearValue                 = 1.0f);
475
476                                                                                                 MultisampleRenderer                     (Context&                                                                                                               context,
477                                                                                                                                                          PipelineConstructionType                                                                               pipelineConstructionType,
478                                                                                                                                                          const VkFormat                                                                                                 colorFormat,
479                                                                                                                                                          const VkFormat                                                                                                 depthStencilFormat,
480                                                                                                                                                          const tcu::IVec2&                                                                                              renderSize,
481                                                                                                                                                          const bool                                                                                                             useDepth,
482                                                                                                                                                          const bool                                                                                                             useStencil,
483                                                                                                                                                          const bool                                                                                                             useConservative,
484                                                                                                                                                          const bool                                                                                                             useFragmentShadingRate,
485                                                                                                                                                          const deUint32                                                                                                 numTopologies,
486                                                                                                                                                          const VkPrimitiveTopology*                                                                             pTopology,
487                                                                                                                                                          const std::vector<Vertex4RGBA>*                                                                pVertices,
488                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&                                    multisampleStateParams,
489                                                                                                                                                          const VkPipelineColorBlendAttachmentState&                                             blendState,
490                                                                                                                                                          const VkPipelineRasterizationConservativeStateCreateInfoEXT&   conservativeStateCreateInfo,
491                                                                                                                                                          const RenderType                                                                                               renderType,
492                                                                                                                                                          const ImageBackingMode                                                                                 backingMode,
493                                                                                                                                                          const float                                                                                                    depthClearValue                 = 1.0f);
494
495         virtual                                                                         ~MultisampleRenderer            (void);
496
497         de::MovePtr<tcu::TextureLevel>                          render                                          (void);
498         de::MovePtr<tcu::TextureLevel>                          getSingleSampledImage           (deUint32 sampleId);
499
500
501 protected:
502         void                                                                            initialize                                      (Context&                                                                               context,
503                                                                                                                                                          const deUint32                                                                 numTopologies,
504                                                                                                                                                          const VkPrimitiveTopology*                                             pTopology,
505                                                                                                                                                          const std::vector<Vertex4RGBA>*                                pVertices);
506
507         Context&                                                                                                        m_context;
508         const PipelineConstructionType                                                          m_pipelineConstructionType;
509
510         const Unique<VkSemaphore>                                                                       m_bindSemaphore;
511
512         const VkFormat                                                                                          m_colorFormat;
513         const VkFormat                                                                                          m_depthStencilFormat;
514         tcu::IVec2                                                                                                      m_renderSize;
515         const bool                                                                                                      m_useDepth;
516         const bool                                                                                                      m_useStencil;
517         const bool                                                                                                      m_useConservative;
518
519         const VkPipelineMultisampleStateCreateInfo                                      m_multisampleStateParams;
520         const VkPipelineColorBlendAttachmentState                                       m_colorBlendState;
521         const VkPipelineRasterizationConservativeStateCreateInfoEXT m_rasterizationConservativeStateCreateInfo;
522
523         const RenderType                                                                                        m_renderType;
524
525         Move<VkImage>                                                                                           m_colorImage;
526         de::MovePtr<Allocation>                                                                         m_colorImageAlloc;
527         Move<VkImageView>                                                                                       m_colorAttachmentView;
528
529         Move<VkImage>                                                                                           m_resolveImage;
530         de::MovePtr<Allocation>                                                                         m_resolveImageAlloc;
531         Move<VkImageView>                                                                                       m_resolveAttachmentView;
532
533         struct PerSampleImage
534         {
535                 Move<VkImage>                                                           m_image;
536                 de::MovePtr<Allocation>                                         m_imageAlloc;
537                 Move<VkImageView>                                                       m_attachmentView;
538         };
539         std::vector<de::SharedPtr<PerSampleImage> >                                     m_perSampleImages;
540
541         Move<VkImage>                                                                                           m_depthStencilImage;
542         de::MovePtr<Allocation>                                                                         m_depthStencilImageAlloc;
543         Move<VkImageView>                                                                                       m_depthStencilAttachmentView;
544
545         Move<VkRenderPass>                                                                                      m_renderPass;
546         Move<VkFramebuffer>                                                                                     m_framebuffer;
547
548         Move<VkShaderModule>                                                                            m_vertexShaderModule;
549         Move<VkShaderModule>                                                                            m_fragmentShaderModule;
550
551         Move<VkShaderModule>                                                                            m_copySampleVertexShaderModule;
552         Move<VkShaderModule>                                                                            m_copySampleFragmentShaderModule;
553
554         Move<VkBuffer>                                                                                          m_vertexBuffer;
555         de::MovePtr<Allocation>                                                                         m_vertexBufferAlloc;
556
557         Move<VkPipelineLayout>                                                                          m_pipelineLayout;
558         std::vector<GraphicsPipelineWrapper>                                            m_graphicsPipelines;
559
560         Move<VkDescriptorSetLayout>                                                                     m_copySampleDesciptorLayout;
561         Move<VkDescriptorPool>                                                                          m_copySampleDesciptorPool;
562         Move<VkDescriptorSet>                                                                           m_copySampleDesciptorSet;
563
564         Move<VkPipelineLayout>                                                                          m_copySamplePipelineLayout;
565         std::vector<GraphicsPipelineWrapper>                                            m_copySamplePipelines;
566
567         Move<VkCommandPool>                                                                                     m_cmdPool;
568         Move<VkCommandBuffer>                                                                           m_cmdBuffer;
569
570         std::vector<de::SharedPtr<Allocation> >                                         m_allocations;
571
572         ImageBackingMode                                                                                        m_backingMode;
573         const float                                                                                                     m_depthClearValue;
574         const bool                                                                                                      m_useFragmentShadingRate;
575 };
576
577 class RasterizationSamplesInstance : public vkt::TestInstance
578 {
579 public:
580                                                                                 RasterizationSamplesInstance    (Context&                                                                               context,
581                                                                                                                                                  const PipelineConstructionType                                 pipelineConstructionType,
582                                                                                                                                                  VkPrimitiveTopology                                                    topology,
583                                                                                                                                                  float                                                                                  pointSize,
584                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
585                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
586                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             blendState,
587                                                                                                                                                  const TestModeFlags                                                    modeFlags,
588                                                                                                                                                  ImageBackingMode                                                               backingMode,
589                                                                                                                                                  const bool                                                                             useFragmentShadingRate);
590         virtual                                                         ~RasterizationSamplesInstance   (void) {}
591
592         virtual tcu::TestStatus                         iterate                                                 (void);
593
594 protected:
595         virtual tcu::TestStatus                         verifyImage                                             (const tcu::ConstPixelBufferAccess& result);
596
597         const VkFormat                                          m_colorFormat;
598         const tcu::IVec2                                        m_renderSize;
599         const VkPrimitiveTopology                       m_primitiveTopology;
600         const float                                                     m_pointSize;
601         const std::vector<Vertex4RGBA>          m_vertices;
602         const std::vector<Vertex4RGBA>          m_fullQuadVertices;                     //!< used by depth/stencil case
603         const TestModeFlags                                     m_modeFlags;
604         de::MovePtr<MultisampleRenderer>        m_multisampleRenderer;
605         const bool                                                      m_useFragmentShadingRate;
606 };
607
608 class MinSampleShadingInstance : public vkt::TestInstance
609 {
610 public:
611                                                                                                 MinSampleShadingInstance        (Context&                                                                               context,
612                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
613                                                                                                                                                          VkPrimitiveTopology                                                    topology,
614                                                                                                                                                          float                                                                                  pointSize,
615                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
616                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
617                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
618                                                                                                                                                          ImageBackingMode                                                               backingMode,
619                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
620         virtual                                                                         ~MinSampleShadingInstance       (void) {}
621
622         virtual tcu::TestStatus                                         iterate                                         (void);
623
624 protected:
625         virtual tcu::TestStatus                                         verifySampleShadedImage         (const std::vector<tcu::TextureLevel>& testShadingImages,
626                                                                                                                                                          const tcu::ConstPixelBufferAccess& noSampleshadingImage);
627
628         const PipelineConstructionType                          m_pipelineConstructionType;
629         const VkFormat                                                          m_colorFormat;
630         const tcu::IVec2                                                        m_renderSize;
631         const VkPrimitiveTopology                                       m_primitiveTopology;
632         const std::vector<Vertex4RGBA>                          m_vertices;
633         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
634         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
635         const ImageBackingMode                                          m_backingMode;
636         const bool                                                                      m_useFragmentShadingRate;
637 };
638
639 class MinSampleShadingDisabledInstance : public MinSampleShadingInstance
640 {
641 public:
642                                                                                                 MinSampleShadingDisabledInstance        (Context&                                                                               context,
643                                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
644                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
645                                                                                                                                                                          float                                                                                  pointSize,
646                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
647                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
648                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
649                                                                                                                                                                          ImageBackingMode                                                               backingMode,
650                                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
651         virtual                                                                         ~MinSampleShadingDisabledInstance       (void) {}
652
653 protected:
654         virtual tcu::TestStatus                                         verifySampleShadedImage                         (const std::vector<tcu::TextureLevel>&  sampleShadedImages,
655                                                                                                                                                                          const tcu::ConstPixelBufferAccess&             noSampleshadingImage);
656 };
657
658 class SampleMaskInstance : public vkt::TestInstance
659 {
660 public:
661                                                                                                 SampleMaskInstance                      (Context&                                                                               context,
662                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
663                                                                                                                                                          VkPrimitiveTopology                                                    topology,
664                                                                                                                                                          float                                                                                  pointSize,
665                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
666                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
667                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
668                                                                                                                                                          ImageBackingMode                                                               backingMode,
669                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
670         virtual                                                                         ~SampleMaskInstance                     (void) {}
671
672         virtual tcu::TestStatus                                         iterate                                         (void);
673
674 protected:
675         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& testShadingImage,
676                                                                                                                                                          const tcu::ConstPixelBufferAccess& minShadingImage,
677                                                                                                                                                          const tcu::ConstPixelBufferAccess& maxShadingImage);
678         const PipelineConstructionType                          m_pipelineConstructionType;
679         const VkFormat                                                          m_colorFormat;
680         const tcu::IVec2                                                        m_renderSize;
681         const VkPrimitiveTopology                                       m_primitiveTopology;
682         const std::vector<Vertex4RGBA>                          m_vertices;
683         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
684         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
685         const ImageBackingMode                                          m_backingMode;
686         const bool                                                                      m_useFragmentShadingRate;
687 };
688
689 class AlphaToOneInstance : public vkt::TestInstance
690 {
691 public:
692                                                                                                 AlphaToOneInstance                      (Context&                                                                               context,
693                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
694                                                                                                                                                          VkPrimitiveTopology                                                    topology,
695                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
696                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
697                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
698                                                                                                                                                          ImageBackingMode                                                               backingMode,
699                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
700         virtual                                                                         ~AlphaToOneInstance                     (void) {}
701
702         virtual tcu::TestStatus                                         iterate                                         (void);
703
704 protected:
705         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& alphaOneImage,
706                                                                                                                                                          const tcu::ConstPixelBufferAccess& noAlphaOneImage);
707         const PipelineConstructionType                          m_pipelineConstructionType;
708         const VkFormat                                                          m_colorFormat;
709         const tcu::IVec2                                                        m_renderSize;
710         const VkPrimitiveTopology                                       m_primitiveTopology;
711         const std::vector<Vertex4RGBA>                          m_vertices;
712         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
713         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
714         const ImageBackingMode                                          m_backingMode;
715         const bool                                                                      m_useFragmentShadingRate;
716 };
717
718 class AlphaToCoverageInstance : public vkt::TestInstance
719 {
720 public:
721                                                                                                 AlphaToCoverageInstance         (Context&                                                                               context,
722                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
723                                                                                                                                                          VkPrimitiveTopology                                                    topology,
724                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
725                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
726                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
727                                                                                                                                                          GeometryType                                                                   geometryType,
728                                                                                                                                                          ImageBackingMode                                                               backingMode,
729                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
730         virtual                                                                         ~AlphaToCoverageInstance        (void) {}
731
732         virtual tcu::TestStatus                                         iterate                                         (void);
733
734 protected:
735         virtual tcu::TestStatus                                         verifyImage                                     (const tcu::ConstPixelBufferAccess& result);
736
737         const PipelineConstructionType                          m_pipelineConstructionType;
738         const VkFormat                                                          m_colorFormat;
739         const tcu::IVec2                                                        m_renderSize;
740         const VkPrimitiveTopology                                       m_primitiveTopology;
741         const std::vector<Vertex4RGBA>                          m_vertices;
742         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
743         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
744         const GeometryType                                                      m_geometryType;
745         const ImageBackingMode                                          m_backingMode;
746         const bool                                                                      m_useFragmentShadingRate;
747 };
748
749 class AlphaToCoverageNoColorAttachmentInstance : public vkt::TestInstance
750 {
751 public:
752                                                                                                 AlphaToCoverageNoColorAttachmentInstance        (Context&                                                                               context,
753                                                                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
754                                                                                                                                                                                          VkPrimitiveTopology                                                    topology,
755                                                                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
756                                                                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
757                                                                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
758                                                                                                                                                                                          GeometryType                                                                   geometryType,
759                                                                                                                                                                                          ImageBackingMode                                                               backingMode,
760                                                                                                                                                                                          const bool                                                                             useFragmentShadingRate);
761         virtual                                                                         ~AlphaToCoverageNoColorAttachmentInstance       (void) {}
762
763         virtual tcu::TestStatus                                         iterate                                                                         (void);
764
765 protected:
766         virtual tcu::TestStatus                                         verifyImage                                                                     (const tcu::ConstPixelBufferAccess& result);
767
768         const PipelineConstructionType                          m_pipelineConstructionType;
769         const VkFormat                                                          m_colorFormat;
770         const VkFormat                                                          m_depthStencilFormat;
771         const tcu::IVec2                                                        m_renderSize;
772         const VkPrimitiveTopology                                       m_primitiveTopology;
773         const std::vector<Vertex4RGBA>                          m_vertices;
774         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
775         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
776         const GeometryType                                                      m_geometryType;
777         const ImageBackingMode                                          m_backingMode;
778         const bool                                                                      m_useFragmentShadingRate;
779 };
780
781 class AlphaToCoverageColorUnusedAttachmentInstance : public vkt::TestInstance
782 {
783 public:
784                                                                                                 AlphaToCoverageColorUnusedAttachmentInstance    (Context&                                                                               context,
785                                                                                                                                                                                                  const PipelineConstructionType                                 pipelineConstructionType,
786                                                                                                                                                                                                  VkPrimitiveTopology                                                    topology,
787                                                                                                                                                                                                  const std::vector<Vertex4RGBA>&                                vertices,
788                                                                                                                                                                                                  const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
789                                                                                                                                                                                                  const VkPipelineColorBlendAttachmentState&             blendState,
790                                                                                                                                                                                                  GeometryType                                                                   geometryType,
791                                                                                                                                                                                                  ImageBackingMode                                                               backingMode,
792                                                                                                                                                                                                  const bool                                                                             useFragmentShadingRate);
793         virtual                                                                         ~AlphaToCoverageColorUnusedAttachmentInstance   (void) {}
794
795         virtual tcu::TestStatus                                         iterate                                                                                 (void);
796
797 protected:
798         virtual tcu::TestStatus                                         verifyImage                                                                             (const tcu::ConstPixelBufferAccess& result);
799
800         const PipelineConstructionType                          m_pipelineConstructionType;
801         const VkFormat                                                          m_colorFormat;
802         const tcu::IVec2                                                        m_renderSize;
803         const VkPrimitiveTopology                                       m_primitiveTopology;
804         const std::vector<Vertex4RGBA>                          m_vertices;
805         const VkPipelineMultisampleStateCreateInfo      m_multisampleStateParams;
806         const VkPipelineColorBlendAttachmentState       m_colorBlendState;
807         const GeometryType                                                      m_geometryType;
808         const ImageBackingMode                                          m_backingMode;
809         const bool                                                                      m_useFragmentShadingRate;
810 };
811
812 class SampleMaskWithConservativeInstance : public vkt::TestInstance
813 {
814 public:
815                                                                                                                         SampleMaskWithConservativeInstance                      (Context&                                                                       context,
816                                                                                                                                                                                                                  const PipelineConstructionType                         pipelineConstructionType,
817                                                                                                                                                                                                                  const VkSampleCountFlagBits                            rasterizationSamples,
818                                                                                                                                                                                                                  const bool                                                                     enableMinSampleShading,
819                                                                                                                                                                                                                  const float                                                            minSampleShading,
820                                                                                                                                                                                                                  const bool                                                                     enableSampleMask,
821                                                                                                                                                                                                                  const VkSampleMask                                                     sampleMask,
822                                                                                                                                                                                                                  const VkConservativeRasterizationModeEXT       conservativeRasterizationMode,
823                                                                                                                                                                                                                  const bool                                                                     enablePostDepthCoverage,
824                                                                                                                                                                                                                  const bool                                                                     enableFullyCoveredEXT,
825                                                                                                                                                                                                                  const RenderType                                                       renderType,
826                                                                                                                                                                                                                  const bool                                                                     useFragmentShadingRate);
827                                                                                                                         ~SampleMaskWithConservativeInstance                     (void) {}
828
829         tcu::TestStatus                                                                                 iterate                                                                         (void);
830
831 protected:
832         VkPipelineMultisampleStateCreateInfo                                    getMultisampleState                                                     (const VkSampleCountFlagBits rasterizationSamples, const bool enableMinSampleShading, const float minSampleShading, const bool enableSampleMask);
833         VkPipelineRasterizationConservativeStateCreateInfoEXT   getRasterizationConservativeStateCreateInfo     (const VkConservativeRasterizationModeEXT       conservativeRasterizationMode);
834         std::vector<Vertex4RGBA>                                                                generateVertices                                                        (void);
835         tcu::TestStatus                                                                                 verifyImage                                                                     (const std::vector<tcu::TextureLevel>& sampleShadedImages,  const tcu::ConstPixelBufferAccess&          result);
836
837         const PipelineConstructionType                                                          m_pipelineConstructionType;
838         const VkSampleCountFlagBits                                                                     m_rasterizationSamples;
839         const bool                                                                                                      m_enablePostDepthCoverage;
840         const bool                                                                                                      m_enableFullyCoveredEXT;
841         const VkFormat                                                                                          m_colorFormat;
842         const VkFormat                                                                                          m_depthStencilFormat;
843         const tcu::IVec2                                                                                        m_renderSize;
844         const bool                                                                                                      m_useDepth;
845         const bool                                                                                                      m_useStencil;
846         const bool                                                                                                      m_useConservative;
847         const bool                                                                                                      m_useFragmentShadingRate;
848         const VkConservativeRasterizationModeEXT                                        m_conservativeRasterizationMode;
849         const VkPrimitiveTopology                                                                       m_topology;
850         const tcu::Vec4                                                                                         m_renderColor;
851         const float                                                                                                     m_depthClearValue;
852         const std::vector<Vertex4RGBA>                                                          m_vertices;
853         const bool                                                                                                      m_enableSampleMask;
854         const std::vector<VkSampleMask>                                                         m_sampleMask;
855         const bool                                                                                                      m_enableMinSampleShading;
856         const float                                                                                                     m_minSampleShading;
857         const VkPipelineMultisampleStateCreateInfo                                      m_multisampleStateParams;
858         const VkPipelineRasterizationConservativeStateCreateInfoEXT m_rasterizationConservativeStateCreateInfo;
859         const VkPipelineColorBlendAttachmentState                                       m_blendState;
860         const RenderType                                                                                        m_renderType;
861         const ImageBackingMode                                                                          m_imageBackingMode;
862 };
863
864 #ifndef CTS_USES_VULKANSC
865 class SampleMaskWithDepthTestInstance : public vkt::TestInstance
866 {
867 public:
868                                                                                                         SampleMaskWithDepthTestInstance         (Context&                                                       context,
869                                                                                                                                                                                  const PipelineConstructionType         pipelineConstructionType,
870                                                                                                                                                                                  const VkSampleCountFlagBits            rasterizationSamples,
871                                                                                                                                                                                  const bool                                                     enablePostDepthCoverage,
872                                                                                                                                                                                  const bool                                                     useFragmentShadingRate);
873                                                                                                         ~SampleMaskWithDepthTestInstance        (void) {}
874
875         tcu::TestStatus                                                                 iterate                                                         (void);
876
877 protected:
878         VkPipelineMultisampleStateCreateInfo                    getMultisampleState                                     (const VkSampleCountFlagBits            rasterizationSamples);
879         std::vector<Vertex4RGBA>                                                generateVertices                                        (void);
880         tcu::TestStatus                                                                 verifyImage                                                     (const tcu::ConstPixelBufferAccess&     result);
881
882         struct SampleCoverage
883         {
884                 SampleCoverage() {}
885                 SampleCoverage(deUint32 min_, deUint32 max_)
886                         : min(min_), max(max_) {}
887
888                 deUint32        min;
889                 deUint32        max;
890         };
891
892         const PipelineConstructionType                                  m_pipelineConstructionType;
893         const VkSampleCountFlagBits                                             m_rasterizationSamples;
894         const bool                                                                              m_enablePostDepthCoverage;
895         const VkFormat                                                                  m_colorFormat;
896         const VkFormat                                                                  m_depthStencilFormat;
897         const tcu::IVec2                                                                m_renderSize;
898         const bool                                                                              m_useDepth;
899         const bool                                                                              m_useStencil;
900         const VkPrimitiveTopology                                               m_topology;
901         const tcu::Vec4                                                                 m_renderColor;
902         const std::vector<Vertex4RGBA>                                  m_vertices;
903         const VkPipelineMultisampleStateCreateInfo              m_multisampleStateParams;
904         const VkPipelineColorBlendAttachmentState               m_blendState;
905         const RenderType                                                                m_renderType;
906         const ImageBackingMode                                                  m_imageBackingMode;
907         const float                                                                             m_depthClearValue;
908         std::map<VkSampleCountFlagBits, SampleCoverage> m_refCoverageAfterDepthTest;
909         const bool                                                                              m_useFragmentShadingRate;
910 };
911
912
913 // Helper functions
914
915 void checkSupport (Context& context, MultisampleTestParams params)
916 {
917         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), params.pipelineConstructionType);
918 }
919 #endif // CTS_USES_VULKANSC
920
921 void initMultisamplePrograms (SourceCollections& sources, MultisampleTestParams params)
922 {
923         const std::string       pointSize               = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("    gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
924         std::ostringstream      vertexSource;
925
926         vertexSource <<
927                 "#version 310 es\n"
928                 "layout(location = 0) in vec4 position;\n"
929                 "layout(location = 1) in vec4 color;\n"
930                 "layout(location = 0) out highp vec4 vtxColor;\n"
931                 "void main (void)\n"
932                 "{\n"
933                 "       gl_Position = position;\n"
934                 "       vtxColor = color;\n"
935                 << pointSize
936                 << "}\n";
937
938         static const char* fragmentSource =
939                 "#version 310 es\n"
940                 "layout(location = 0) in highp vec4 vtxColor;\n"
941                 "layout(location = 0) out highp vec4 fragColor;\n"
942                 "void main (void)\n"
943                 "{\n"
944                 "       fragColor = vtxColor;\n"
945                 "}\n";
946
947         sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
948         sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
949 }
950
951 void initSampleShadingPrograms (SourceCollections& sources, MultisampleTestParams params)
952 {
953         {
954                 const std::string       pointSize               = params.geometryType == GEOMETRY_TYPE_OPAQUE_POINT ? (std::string("    gl_PointSize = ") + de::toString(params.pointSize) + ".0f;\n") : std::string("");
955                 std::ostringstream      vertexSource;
956
957                 vertexSource <<
958                         "#version 440\n"
959                         "layout(location = 0) in vec4 position;\n"
960                         "layout(location = 1) in vec4 color;\n"
961                         "void main (void)\n"
962                         "{\n"
963                         "       gl_Position = position;\n"
964                         << pointSize
965                         << "}\n";
966
967                 static const char* fragmentSource =
968                         "#version 440\n"
969                         "layout(location = 0) out highp vec4 fragColor;\n"
970                         "void main (void)\n"
971                         "{\n"
972                         "       fragColor = vec4(fract(gl_FragCoord.xy), 0.0, 1.0);\n"
973                         "}\n";
974
975                 sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
976                 sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
977         }
978
979         {
980                 static const char*  vertexSource =
981                         "#version 440\n"
982                         "void main (void)\n"
983                         "{\n"
984                         "       const vec4 positions[4] = vec4[4](\n"
985                         "               vec4(-1.0, -1.0, 0.0, 1.0),\n"
986                         "               vec4(-1.0,  1.0, 0.0, 1.0),\n"
987                         "               vec4( 1.0, -1.0, 0.0, 1.0),\n"
988                         "               vec4( 1.0,  1.0, 0.0, 1.0)\n"
989                         "       );\n"
990                         "       gl_Position = positions[gl_VertexIndex];\n"
991                         "}\n";
992
993                 static const char* fragmentSource =
994                         "#version 440\n"
995                         "precision highp float;\n"
996                         "layout(location = 0) out highp vec4 fragColor;\n"
997                         "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
998                         "layout(push_constant) uniform PushConstantsBlock\n"
999                         "{\n"
1000                         "       int sampleId;\n"
1001                         "} pushConstants;\n"
1002                         "void main (void)\n"
1003                         "{\n"
1004                         "       fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
1005                         "}\n";
1006
1007                 sources.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
1008                 sources.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
1009         }
1010 }
1011
1012 void initAlphaToCoverageColorUnusedAttachmentPrograms (SourceCollections& sources)
1013 {
1014         std::ostringstream vertexSource;
1015
1016         vertexSource <<
1017                 "#version 310 es\n"
1018                 "layout(location = 0) in vec4 position;\n"
1019                 "layout(location = 1) in vec4 color;\n"
1020                 "layout(location = 0) out highp vec4 vtxColor;\n"
1021                 "void main (void)\n"
1022                 "{\n"
1023                 "       gl_Position = position;\n"
1024                 "       vtxColor = color;\n"
1025                 "}\n";
1026
1027         // Location 0 is unused, but the alpha for coverage is written there. Location 1 has no alpha channel.
1028         static const char* fragmentSource =
1029                 "#version 310 es\n"
1030                 "layout(location = 0) in highp vec4 vtxColor;\n"
1031                 "layout(location = 0) out highp vec4 fragColor0;\n"
1032                 "layout(location = 1) out highp vec3 fragColor1;\n"
1033                 "void main (void)\n"
1034                 "{\n"
1035                 "       fragColor0 = vtxColor;\n"
1036                 "       fragColor1 = vtxColor.rgb;\n"
1037                 "}\n";
1038
1039         sources.glslSources.add("color_vert") << glu::VertexSource(vertexSource.str());
1040         sources.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource);
1041 }
1042
1043 bool isSupportedSampleCount (const InstanceInterface& instanceInterface, VkPhysicalDevice physicalDevice, VkSampleCountFlagBits rasterizationSamples)
1044 {
1045         VkPhysicalDeviceProperties deviceProperties;
1046
1047         instanceInterface.getPhysicalDeviceProperties(physicalDevice, &deviceProperties);
1048
1049         return !!(deviceProperties.limits.framebufferColorSampleCounts & rasterizationSamples);
1050 }
1051
1052 bool checkFragmentShadingRateRequirements(Context& context, deUint32 sampleCount)
1053 {
1054         const auto&     vki = context.getInstanceInterface();
1055         const auto      physicalDevice = context.getPhysicalDevice();
1056
1057         context.requireDeviceFunctionality("VK_KHR_fragment_shading_rate");
1058
1059         if (!context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
1060                 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate not supported");
1061
1062         // Fetch information about supported fragment shading rates
1063         deUint32 supportedFragmentShadingRateCount = 0;
1064         vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, DE_NULL);
1065
1066         std::vector<vk::VkPhysicalDeviceFragmentShadingRateKHR> supportedFragmentShadingRates(supportedFragmentShadingRateCount,
1067                 {
1068                         vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_KHR,
1069                         DE_NULL,
1070                         vk::VK_SAMPLE_COUNT_1_BIT,
1071                         {1, 1}
1072                 });
1073         vki.getPhysicalDeviceFragmentShadingRatesKHR(physicalDevice, &supportedFragmentShadingRateCount, supportedFragmentShadingRates.data());
1074
1075         for (const auto& rate : supportedFragmentShadingRates)
1076         {
1077                 if ((rate.fragmentSize.width == 2u) &&
1078                         (rate.fragmentSize.height == 2u) &&
1079                         (rate.sampleCounts & sampleCount))
1080                         return true;
1081         }
1082
1083         return false;
1084 }
1085
1086 VkPipelineColorBlendAttachmentState getDefaultColorBlendAttachmentState (void)
1087 {
1088         const VkPipelineColorBlendAttachmentState colorBlendState =
1089         {
1090                 false,                                                                                                          // VkBool32                                     blendEnable;
1091                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
1092                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
1093                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
1094                 VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
1095                 VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
1096                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
1097                 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
1098                         VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1099         };
1100
1101         return colorBlendState;
1102 }
1103
1104 deUint32 getUniqueColorsCount (const tcu::ConstPixelBufferAccess& image)
1105 {
1106         DE_ASSERT(image.getFormat().getPixelSize() == 4);
1107
1108         std::map<deUint32, deUint32>    histogram; // map<pixel value, number of occurrences>
1109         const deUint32                                  pixelCount      = image.getWidth() * image.getHeight() * image.getDepth();
1110
1111         for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
1112         {
1113                 const deUint32 pixelValue = *((const deUint32*)image.getDataPtr() + pixelNdx);
1114
1115                 if (histogram.find(pixelValue) != histogram.end())
1116                         histogram[pixelValue]++;
1117                 else
1118                         histogram[pixelValue] = 1;
1119         }
1120
1121         return (deUint32)histogram.size();
1122 }
1123
1124 VkImageAspectFlags getImageAspectFlags (const VkFormat format)
1125 {
1126         const tcu::TextureFormat tcuFormat = mapVkFormat(format);
1127
1128         if      (tcuFormat.order == tcu::TextureFormat::DS)             return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1129         else if (tcuFormat.order == tcu::TextureFormat::D)              return VK_IMAGE_ASPECT_DEPTH_BIT;
1130         else if (tcuFormat.order == tcu::TextureFormat::S)              return VK_IMAGE_ASPECT_STENCIL_BIT;
1131
1132         DE_ASSERT(false);
1133         return 0u;
1134 }
1135
1136 std::vector<Vertex4RGBA> generateVertices (const GeometryType geometryType)
1137 {
1138         std::vector<Vertex4RGBA> vertices;
1139
1140         switch (geometryType)
1141         {
1142                 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
1143                 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:
1144                 {
1145                         Vertex4RGBA vertexData[3] =
1146                         {
1147                                 {
1148                                         tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
1149                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1150                                 },
1151                                 {
1152                                         tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
1153                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1154                                 },
1155                                 {
1156                                         tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
1157                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1158                                 }
1159                         };
1160
1161                         if (geometryType == GEOMETRY_TYPE_INVISIBLE_TRIANGLE)
1162                         {
1163                                 for (int i = 0; i < 3; i++)
1164                                         vertexData[i].color = tcu::Vec4();
1165                         }
1166
1167                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 3);
1168                         break;
1169                 }
1170
1171                 case GEOMETRY_TYPE_OPAQUE_LINE:
1172                 {
1173                         const Vertex4RGBA vertexData[2] =
1174                         {
1175                                 {
1176                                         tcu::Vec4(-0.75f, 0.25f, 0.0f, 1.0f),
1177                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1178                                 },
1179                                 {
1180                                         tcu::Vec4(0.75f, -0.25f, 0.0f, 1.0f),
1181                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1182                                 }
1183                         };
1184
1185                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 2);
1186                         break;
1187                 }
1188
1189                 case GEOMETRY_TYPE_OPAQUE_POINT:
1190                 {
1191                         const Vertex4RGBA vertex =
1192                         {
1193                                 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
1194                                 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1195                         };
1196
1197                         vertices = std::vector<Vertex4RGBA>(1, vertex);
1198                         break;
1199                 }
1200
1201                 case GEOMETRY_TYPE_OPAQUE_QUAD:
1202                 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
1203                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1204                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
1205                 case GEOMETRY_TYPE_GRADIENT_QUAD:
1206                 {
1207                         Vertex4RGBA vertexData[4] =
1208                         {
1209                                 {
1210                                         tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
1211                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1212                                 },
1213                                 {
1214                                         tcu::Vec4(1.0f, -1.0f, 0.0f, 1.0f),
1215                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1216                                 },
1217                                 {
1218                                         tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
1219                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1220                                 },
1221                                 {
1222                                         tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f),
1223                                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
1224                                 }
1225                         };
1226
1227                         if (geometryType == GEOMETRY_TYPE_TRANSLUCENT_QUAD)
1228                         {
1229                                 for (int i = 0; i < 4; i++)
1230                                         vertexData[i].color.w() = 0.25f;
1231                         }
1232                         else if (geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD)
1233                         {
1234                                 for (int i = 0; i < 4; i++)
1235                                         vertexData[i].color.w() = 0.0f;
1236                         }
1237                         else if (geometryType == GEOMETRY_TYPE_GRADIENT_QUAD)
1238                         {
1239                                 vertexData[0].color.w() = 0.0f;
1240                                 vertexData[2].color.w() = 0.0f;
1241                         }
1242                         else if (geometryType == GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH)
1243                         {
1244                                 for (int i = 0; i < 4; i++)
1245                                         vertexData[i].position.z() = 0.5f;
1246                         }
1247
1248                         vertices = std::vector<Vertex4RGBA>(vertexData, vertexData + 4);
1249                         break;
1250                 }
1251
1252                 default:
1253                         DE_ASSERT(false);
1254         }
1255         return vertices;
1256 }
1257
1258 VkPrimitiveTopology getPrimitiveTopology (const GeometryType geometryType)
1259 {
1260         switch (geometryType)
1261         {
1262                 case GEOMETRY_TYPE_OPAQUE_TRIANGLE:
1263                 case GEOMETRY_TYPE_INVISIBLE_TRIANGLE:                  return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1264
1265                 case GEOMETRY_TYPE_OPAQUE_LINE:                                 return VK_PRIMITIVE_TOPOLOGY_LINE_LIST;
1266                 case GEOMETRY_TYPE_OPAQUE_POINT:                                return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
1267
1268                 case GEOMETRY_TYPE_OPAQUE_QUAD:
1269                 case GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH:
1270                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
1271                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
1272                 case GEOMETRY_TYPE_GRADIENT_QUAD:                               return VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP;
1273
1274                 default:
1275                         DE_ASSERT(false);
1276                         return VK_PRIMITIVE_TOPOLOGY_LAST;
1277         }
1278 }
1279
1280 bool isSupportedDepthStencilFormat (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
1281 {
1282         VkFormatProperties formatProps;
1283         vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
1284         return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
1285 }
1286
1287 VkFormat findSupportedDepthStencilFormat (Context& context, const bool useDepth, const bool useStencil)
1288 {
1289         if (useDepth && !useStencil)
1290                 return VK_FORMAT_D16_UNORM;             // must be supported
1291
1292         const InstanceInterface&        vki                     = context.getInstanceInterface();
1293         const VkPhysicalDevice          physDevice      = context.getPhysicalDevice();
1294
1295         // One of these formats must be supported.
1296
1297         if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
1298                 return VK_FORMAT_D24_UNORM_S8_UINT;
1299
1300         if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D32_SFLOAT_S8_UINT))
1301                 return VK_FORMAT_D32_SFLOAT_S8_UINT;
1302
1303         return VK_FORMAT_UNDEFINED;
1304 }
1305
1306
1307 // MultisampleTest
1308
1309 MultisampleTest::MultisampleTest (tcu::TestContext&                                                             testContext,
1310                                                                   const std::string&                                                    name,
1311                                                                   const std::string&                                                    description,
1312                                                                   const PipelineConstructionType                                pipelineConstructionType,
1313                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
1314                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
1315                                                                   GeometryType                                                                  geometryType,
1316                                                                   float                                                                                 pointSize,
1317                                                                   ImageBackingMode                                                              backingMode,
1318                                                                   const bool                                                                    useFragmentShadingRate)
1319         : vkt::TestCase                         (testContext, name, description)
1320         , m_pipelineConstructionType(pipelineConstructionType)
1321         , m_multisampleStateParams      (multisampleStateParams)
1322         , m_colorBlendState                     (blendState)
1323         , m_geometryType                        (geometryType)
1324         , m_pointSize                           (pointSize)
1325         , m_backingMode                         (backingMode)
1326         , m_useFragmentShadingRate      (useFragmentShadingRate)
1327 {
1328         if (m_multisampleStateParams.pSampleMask)
1329         {
1330                 // Copy pSampleMask to avoid dependencies with other classes
1331
1332                 const deUint32 maskCount = deCeilFloatToInt32(float(m_multisampleStateParams.rasterizationSamples) / 32);
1333
1334                 for (deUint32 maskNdx = 0; maskNdx < maskCount; maskNdx++)
1335                         m_sampleMask.push_back(m_multisampleStateParams.pSampleMask[maskNdx]);
1336
1337                 m_multisampleStateParams.pSampleMask = m_sampleMask.data();
1338         }
1339 }
1340
1341 void MultisampleTest::initPrograms (SourceCollections& programCollection) const
1342 {
1343         MultisampleTestParams params = {m_pipelineConstructionType, m_geometryType, m_pointSize, m_backingMode, m_useFragmentShadingRate};
1344         initMultisamplePrograms(programCollection, params);
1345 }
1346
1347 TestInstance* MultisampleTest::createInstance (Context& context) const
1348 {
1349         return createMultisampleTestInstance(context, getPrimitiveTopology(m_geometryType), m_pointSize, generateVertices(m_geometryType), m_multisampleStateParams, m_colorBlendState);
1350 }
1351
1352 void MultisampleTest::checkSupport (Context& context) const
1353 {
1354         if (m_geometryType == GEOMETRY_TYPE_OPAQUE_POINT && m_pointSize > 1.0f)
1355                 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_LARGE_POINTS);
1356
1357         if (m_useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_multisampleStateParams.rasterizationSamples))
1358                 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
1359
1360         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1361 }
1362
1363 // RasterizationSamplesTest
1364
1365 RasterizationSamplesTest::RasterizationSamplesTest (tcu::TestContext&                   testContext,
1366                                                                                                         const std::string&                      name,
1367                                                                                                         const std::string&                      description,
1368                                                                                                         PipelineConstructionType        pipelineConstructionType,
1369                                                                                                         VkSampleCountFlagBits           rasterizationSamples,
1370                                                                                                         GeometryType                            geometryType,
1371                                                                                                         float                                           pointSize,
1372                                                                                                         ImageBackingMode                        backingMode,
1373                                                                                                         TestModeFlags                           modeFlags,
1374                                                                                                         const bool                                      useFragmentShadingRate)
1375         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getRasterizationSamplesStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate)
1376         , m_backingMode         (backingMode)
1377         , m_modeFlags           (modeFlags)
1378 {
1379 }
1380
1381 VkPipelineMultisampleStateCreateInfo RasterizationSamplesTest::getRasterizationSamplesStateParams (VkSampleCountFlagBits rasterizationSamples)
1382 {
1383         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1384         {
1385                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1386                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1387                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1388                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1389                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1390                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1391                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1392                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
1393                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1394         };
1395
1396         return multisampleStateParams;
1397 }
1398
1399 TestInstance* RasterizationSamplesTest::createMultisampleTestInstance (Context&                                                                         context,
1400                                                                                                                                            VkPrimitiveTopology                                                  topology,
1401                                                                                                                                            float                                                                                pointSize,
1402                                                                                                                                            const std::vector<Vertex4RGBA>&                              vertices,
1403                                                                                                                                            const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
1404                                                                                                                                            const VkPipelineColorBlendAttachmentState&   colorBlendState) const
1405 {
1406         return new RasterizationSamplesInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_modeFlags, m_backingMode, m_useFragmentShadingRate);
1407 }
1408
1409
1410 // MinSampleShadingTest
1411
1412 MinSampleShadingTest::MinSampleShadingTest (tcu::TestContext&                           testContext,
1413                                                                                         const std::string&                              name,
1414                                                                                         const std::string&                              description,
1415                                                                                         const PipelineConstructionType  pipelineConstructionType,
1416                                                                                         VkSampleCountFlagBits                   rasterizationSamples,
1417                                                                                         float                                                   minSampleShading,
1418                                                                                         GeometryType                                    geometryType,
1419                                                                                         float                                                   pointSize,
1420                                                                                         ImageBackingMode                                backingMode,
1421                                                                                         const bool                                              minSampleShadingEnabled,
1422                                                                                         const bool                                              useFragmentShadingRate)
1423         : MultisampleTest                       (testContext, name, description, pipelineConstructionType, getMinSampleShadingStateParams(rasterizationSamples, minSampleShading, minSampleShadingEnabled), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate)
1424         , m_pointSize                           (pointSize)
1425         , m_backingMode                         (backingMode)
1426         , m_minSampleShadingEnabled     (minSampleShadingEnabled)
1427 {
1428 }
1429
1430 void MinSampleShadingTest::checkSupport (Context& context) const
1431 {
1432         MultisampleTest::checkSupport(context);
1433
1434         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_SAMPLE_RATE_SHADING);
1435 }
1436
1437 void MinSampleShadingTest::initPrograms (SourceCollections& programCollection) const
1438 {
1439         MultisampleTestParams params = {m_pipelineConstructionType, m_geometryType, m_pointSize, m_backingMode, m_useFragmentShadingRate};
1440         initSampleShadingPrograms(programCollection, params);
1441 }
1442
1443 TestInstance* MinSampleShadingTest::createMultisampleTestInstance (Context&                                                                             context,
1444                                                                                                                                    VkPrimitiveTopology                                                  topology,
1445                                                                                                                                    float                                                                                pointSize,
1446                                                                                                                                    const std::vector<Vertex4RGBA>&                              vertices,
1447                                                                                                                                    const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
1448                                                                                                                                    const VkPipelineColorBlendAttachmentState&   colorBlendState) const
1449 {
1450         if (m_minSampleShadingEnabled)
1451                 return new MinSampleShadingInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate);
1452         else
1453                 return new MinSampleShadingDisabledInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate);
1454 }
1455
1456 VkPipelineMultisampleStateCreateInfo MinSampleShadingTest::getMinSampleShadingStateParams (VkSampleCountFlagBits rasterizationSamples, float minSampleShading, bool minSampleShadingEnabled)
1457 {
1458         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1459         {
1460                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1461                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1462                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1463                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1464                 minSampleShadingEnabled ? VK_TRUE : VK_FALSE,                           // VkBool32                                                                     sampleShadingEnable;
1465                 minSampleShading,                                                                                       // float                                                                        minSampleShading;
1466                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1467                 false,                                                                                                          //  VkBool32                                                            alphaToCoverageEnable;
1468                 false                                                                                                           //  VkBool32                                                            alphaToOneEnable;
1469         };
1470
1471         return multisampleStateParams;
1472 }
1473
1474
1475 // SampleMaskTest
1476
1477 SampleMaskTest::SampleMaskTest (tcu::TestContext&                                       testContext,
1478                                                                 const std::string&                                      name,
1479                                                                 const std::string&                                      description,
1480                                                                 const PipelineConstructionType          pipelineConstructionType,
1481                                                                 VkSampleCountFlagBits                           rasterizationSamples,
1482                                                                 const std::vector<VkSampleMask>&        sampleMask,
1483                                                                 GeometryType                                            geometryType,
1484                                                                 float                                                           pointSize,
1485                                                                 ImageBackingMode                                        backingMode,
1486                                                                 const bool                                                      useFragmentShadingRate)
1487         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getSampleMaskStateParams(rasterizationSamples, sampleMask), getDefaultColorBlendAttachmentState(), geometryType, pointSize, backingMode, useFragmentShadingRate)
1488         , m_backingMode         (backingMode)
1489 {
1490 }
1491
1492 TestInstance* SampleMaskTest::createMultisampleTestInstance (Context&                                                                           context,
1493                                                                                                                          VkPrimitiveTopology                                                    topology,
1494                                                                                                                          float                                                                                  pointSize,
1495                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
1496                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
1497                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const
1498 {
1499         DE_UNREF(pointSize);
1500         return new SampleMaskInstance(context, m_pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate);
1501 }
1502
1503 VkPipelineMultisampleStateCreateInfo SampleMaskTest::getSampleMaskStateParams (VkSampleCountFlagBits rasterizationSamples, const std::vector<VkSampleMask>& sampleMask)
1504 {
1505         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1506         {
1507                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1508                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1509                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1510                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1511                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1512                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1513                 sampleMask.data(),                                                                                      // const VkSampleMask*                                          pSampleMask;
1514                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
1515                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1516         };
1517
1518         return multisampleStateParams;
1519 }
1520
1521
1522 // AlphaToOneTest
1523
1524 AlphaToOneTest::AlphaToOneTest (tcu::TestContext&                               testContext,
1525                                                                 const std::string&                              name,
1526                                                                 const std::string&                              description,
1527                                                                 const PipelineConstructionType  pipelineConstructionType,
1528                                                                 VkSampleCountFlagBits                   rasterizationSamples,
1529                                                                 ImageBackingMode                                backingMode,
1530                                                                 const bool                                              useFragmentShadingRate)
1531         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getAlphaToOneStateParams(rasterizationSamples), getAlphaToOneBlendState(), GEOMETRY_TYPE_GRADIENT_QUAD, 1.0f, backingMode, useFragmentShadingRate)
1532         , m_backingMode(backingMode)
1533 {
1534 }
1535
1536 void AlphaToOneTest::checkSupport (Context& context) const
1537 {
1538         MultisampleTest::checkSupport(context);
1539
1540         context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_ALPHA_TO_ONE);
1541 }
1542
1543 TestInstance* AlphaToOneTest::createMultisampleTestInstance (Context&                                                                           context,
1544                                                                                                                          VkPrimitiveTopology                                                    topology,
1545                                                                                                                          float                                                                                  pointSize,
1546                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
1547                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
1548                                                                                                                          const VkPipelineColorBlendAttachmentState&             colorBlendState) const
1549 {
1550         DE_UNREF(pointSize);
1551         return new AlphaToOneInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_backingMode, m_useFragmentShadingRate);
1552 }
1553
1554 VkPipelineMultisampleStateCreateInfo AlphaToOneTest::getAlphaToOneStateParams (VkSampleCountFlagBits rasterizationSamples)
1555 {
1556         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1557         {
1558                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1559                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1560                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1561                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1562                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1563                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1564                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1565                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
1566                 true                                                                                                            // VkBool32                                                                     alphaToOneEnable;
1567         };
1568
1569         return multisampleStateParams;
1570 }
1571
1572 VkPipelineColorBlendAttachmentState AlphaToOneTest::getAlphaToOneBlendState (void)
1573 {
1574         const VkPipelineColorBlendAttachmentState colorBlendState =
1575         {
1576                 true,                                                                                                           // VkBool32                                     blendEnable;
1577                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                      // VkBlendFactor                        srcColorBlendFactor;
1578                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                            // VkBlendFactor                        dstColorBlendFactor;
1579                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
1580                 VK_BLEND_FACTOR_SRC_ALPHA,                                                                      // VkBlendFactor                        srcAlphaBlendFactor;
1581                 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,                                            // VkBlendFactor                        dstAlphaBlendFactor;
1582                 VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
1583                 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
1584                         VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
1585         };
1586
1587         return colorBlendState;
1588 }
1589
1590
1591 // AlphaToCoverageTest
1592
1593 AlphaToCoverageTest::AlphaToCoverageTest (tcu::TestContext&                                     testContext,
1594                                                                                   const std::string&                            name,
1595                                                                                   const std::string&                            description,
1596                                                                                   const PipelineConstructionType        pipelineConstructionType,
1597                                                                                   VkSampleCountFlagBits                         rasterizationSamples,
1598                                                                                   GeometryType                                          geometryType,
1599                                                                                   ImageBackingMode                                      backingMode,
1600                                                                                   const bool                                            useFragmentShadingRate)
1601         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getAlphaToCoverageStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode, useFragmentShadingRate)
1602         , m_geometryType        (geometryType)
1603         , m_backingMode         (backingMode)
1604 {
1605 }
1606
1607 TestInstance* AlphaToCoverageTest::createMultisampleTestInstance (Context&                                                                              context,
1608                                                                                                                                   VkPrimitiveTopology                                                   topology,
1609                                                                                                                                   float                                                                                 pointSize,
1610                                                                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
1611                                                                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
1612                                                                                                                                   const VkPipelineColorBlendAttachmentState&    colorBlendState) const
1613 {
1614         DE_UNREF(pointSize);
1615         return new AlphaToCoverageInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate);
1616 }
1617
1618 VkPipelineMultisampleStateCreateInfo AlphaToCoverageTest::getAlphaToCoverageStateParams (VkSampleCountFlagBits rasterizationSamples)
1619 {
1620         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1621         {
1622                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1623                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1624                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1625                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1626                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1627                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1628                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1629                 true,                                                                                                           // VkBool32                                                                     alphaToCoverageEnable;
1630                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1631         };
1632
1633         return multisampleStateParams;
1634 }
1635
1636 // AlphaToCoverageNoColorAttachmentTest
1637
1638 AlphaToCoverageNoColorAttachmentTest::AlphaToCoverageNoColorAttachmentTest (tcu::TestContext&                           testContext,
1639                                                                                                                                                         const std::string&                              name,
1640                                                                                                                                                         const std::string&                              description,
1641                                                                                                                                                         const PipelineConstructionType  pipelineConstructionType,
1642                                                                                                                                                         VkSampleCountFlagBits                   rasterizationSamples,
1643                                                                                                                                                         GeometryType                                    geometryType,
1644                                                                                                                                                         ImageBackingMode                                backingMode,
1645                                                                                                                                                         const bool                                              useFragmentShadingRate)
1646         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode, useFragmentShadingRate)
1647         , m_geometryType        (geometryType)
1648         , m_backingMode         (backingMode)
1649 {
1650 }
1651
1652 TestInstance* AlphaToCoverageNoColorAttachmentTest::createMultisampleTestInstance (Context&                                                                             context,
1653                                                                                                                                                                    VkPrimitiveTopology                                                  topology,
1654                                                                                                                                                                    float                                                                                pointSize,
1655                                                                                                                                                                    const std::vector<Vertex4RGBA>&                              vertices,
1656                                                                                                                                                                    const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
1657                                                                                                                                                                    const VkPipelineColorBlendAttachmentState&   colorBlendState) const
1658 {
1659         DE_UNREF(pointSize);
1660         return new AlphaToCoverageNoColorAttachmentInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate);
1661 }
1662
1663 VkPipelineMultisampleStateCreateInfo AlphaToCoverageNoColorAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1664 {
1665         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1666         {
1667                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1668                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1669                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1670                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1671                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1672                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1673                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1674                 true,                                                                                                           // VkBool32                                                                     alphaToCoverageEnable;
1675                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1676         };
1677
1678         return multisampleStateParams;
1679 }
1680
1681 // AlphaToCoverageColorUnusedAttachmentTest
1682
1683 AlphaToCoverageColorUnusedAttachmentTest::AlphaToCoverageColorUnusedAttachmentTest (tcu::TestContext&                           testContext,
1684                                                                                                                                                                         const std::string&                              name,
1685                                                                                                                                                                         const std::string&                              description,
1686                                                                                                                                                                         const PipelineConstructionType  pipelineConstructionType,
1687                                                                                                                                                                         VkSampleCountFlagBits                   rasterizationSamples,
1688                                                                                                                                                                         GeometryType                                    geometryType,
1689                                                                                                                                                                         ImageBackingMode                                backingMode,
1690                                                                                                                                                                         const bool                                              useFragmentShadingRate)
1691         : MultisampleTest       (testContext, name, description, pipelineConstructionType, getStateParams(rasterizationSamples), getDefaultColorBlendAttachmentState(), geometryType, 1.0f, backingMode, useFragmentShadingRate)
1692         , m_geometryType        (geometryType)
1693         , m_backingMode         (backingMode)
1694 {
1695 }
1696
1697 void AlphaToCoverageColorUnusedAttachmentTest::initPrograms (SourceCollections& programCollection) const
1698 {
1699         initAlphaToCoverageColorUnusedAttachmentPrograms(programCollection);
1700 }
1701
1702 TestInstance* AlphaToCoverageColorUnusedAttachmentTest::createMultisampleTestInstance (Context&                                                                         context,
1703                                                                                                                                                                            VkPrimitiveTopology                                                  topology,
1704                                                                                                                                                                            float                                                                                pointSize,
1705                                                                                                                                                                            const std::vector<Vertex4RGBA>&                              vertices,
1706                                                                                                                                                                            const VkPipelineMultisampleStateCreateInfo&  multisampleStateParams,
1707                                                                                                                                                                            const VkPipelineColorBlendAttachmentState&   colorBlendState) const
1708 {
1709         DE_UNREF(pointSize);
1710         return new AlphaToCoverageColorUnusedAttachmentInstance(context, m_pipelineConstructionType, topology, vertices, multisampleStateParams, colorBlendState, m_geometryType, m_backingMode, m_useFragmentShadingRate);
1711 }
1712
1713 VkPipelineMultisampleStateCreateInfo AlphaToCoverageColorUnusedAttachmentTest::getStateParams (VkSampleCountFlagBits rasterizationSamples)
1714 {
1715         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
1716         {
1717                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
1718                 DE_NULL,                                                                                                        // const void*                                                          pNext;
1719                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
1720                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
1721                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
1722                 0.0f,                                                                                                           // float                                                                        minSampleShading;
1723                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
1724                 true,                                                                                                           // VkBool32                                                                     alphaToCoverageEnable;
1725                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
1726         };
1727
1728         return multisampleStateParams;
1729 }
1730
1731 // SampleMaskWithConservativeTest
1732 SampleMaskWithConservativeTest::SampleMaskWithConservativeTest (tcu::TestContext&                                                       testContext,
1733                                                                                                                                 const std::string&                                                      name,
1734                                                                                                                                 const std::string&                                                      description,
1735                                                                                                                                 const PipelineConstructionType                          pipelineConstructionType,
1736                                                                                                                                 const VkSampleCountFlagBits                                     rasterizationSamples,
1737                                                                                                                                 const VkConservativeRasterizationModeEXT        conservativeRasterizationMode,
1738                                                                                                                                 const bool                                                                      enableMinSampleShading,
1739                                                                                                                                 const float                                                                     minSampleShading,
1740                                                                                                                                 const bool                                                                      enableSampleMask,
1741                                                                                                                                 const VkSampleMask                                                      sampleMask,
1742                                                                                                                                 const bool                                                                      enablePostDepthCoverage,
1743                                                                                                                                 const bool                                                                      useFragmentShadingRate)
1744         : vkt::TestCase                                         (testContext, name, description)
1745         , m_pipelineConstructionType            (pipelineConstructionType)
1746         , m_rasterizationSamples                        (rasterizationSamples)
1747         , m_enableMinSampleShading                      (enableMinSampleShading)
1748         , m_minSampleShading                            (minSampleShading)
1749         , m_enableSampleMask                            (enableSampleMask)
1750         , m_sampleMask                                          (sampleMask)
1751         , m_conservativeRasterizationMode       (conservativeRasterizationMode)
1752         , m_enablePostDepthCoverage                     (enablePostDepthCoverage)
1753         , m_renderType                                          (RENDER_TYPE_RESOLVE)
1754         , m_useFragmentShadingRate                      (useFragmentShadingRate)
1755 {
1756 }
1757
1758 void SampleMaskWithConservativeTest::checkSupport(Context& context) const
1759 {
1760         if (!context.getDeviceProperties().limits.standardSampleLocations)
1761                 TCU_THROW(NotSupportedError, "standardSampleLocations required");
1762
1763         if (m_useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_rasterizationSamples))
1764                 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
1765
1766         context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
1767
1768         const auto&             conservativeRasterizationProperties     = context.getConservativeRasterizationPropertiesEXT();
1769         const deUint32  subPixelPrecisionBits                           = context.getDeviceProperties().limits.subPixelPrecisionBits;
1770         const deUint32  subPixelPrecision                                       = (1 << subPixelPrecisionBits);
1771         const float             primitiveOverestimationSizeMult         = float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize;
1772
1773         DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8);
1774
1775         if (m_enablePostDepthCoverage)
1776         {
1777                 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1778                 if (!conservativeRasterizationProperties.conservativeRasterizationPostDepthCoverage)
1779                         TCU_THROW(NotSupportedError, "conservativeRasterizationPostDepthCoverage not supported");
1780         }
1781
1782         context.getTestContext().getLog()
1783                 << tcu::TestLog::Message
1784                 << "maxExtraPrimitiveOverestimationSize=" << conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n'
1785                 << "extraPrimitiveOverestimationSizeGranularity=" << conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n'
1786                 << "degenerateTrianglesRasterized=" << conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n'
1787                 << "primitiveOverestimationSize=" << conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n"
1788                 << tcu::TestLog::EndMessage;
1789
1790
1791         if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
1792         {
1793                 if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
1794                         TCU_FAIL("Granularity cannot be greater than maximum extra size");
1795         }
1796         else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
1797         {
1798                 if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE)
1799                         TCU_THROW(NotSupportedError, "Underestimation is not supported");
1800         }
1801         else
1802                 TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class");
1803
1804         if (!conservativeRasterizationProperties.fullyCoveredFragmentShaderInputVariable)
1805         {
1806                 TCU_THROW(NotSupportedError, "FullyCoveredEXT input variable is not supported");
1807         }
1808
1809         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1810 }
1811
1812 void SampleMaskWithConservativeTest::initPrograms(SourceCollections& programCollection) const
1813 {
1814         {
1815                 DE_ASSERT((int)m_rasterizationSamples <= 32);
1816
1817                 static const char* vertexSource =
1818                         "#version 440\n"
1819                         "layout(location = 0) in vec4 position;\n"
1820                         "layout(location = 1) in vec4 color;\n"
1821                         "layout(location = 0) out vec4 vtxColor;\n"
1822                         "out gl_PerVertex\n"
1823                         "{\n"
1824                         "    vec4 gl_Position;\n"
1825                         "};\n"
1826                         "\n"
1827                         "void main (void)\n"
1828                         "{\n"
1829                         "    gl_Position = position;\n"
1830                         "    vtxColor = color;\n"
1831                         "}\n";
1832
1833                 std::ostringstream fragmentSource;
1834                 fragmentSource <<
1835                         "#version 440\n"
1836                         << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "")
1837                         << (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT ? "#extension GL_NV_conservative_raster_underestimation : enable\n" : "") <<
1838                         "layout(early_fragment_tests) in;\n"
1839                         << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1840                         "layout(location = 0) in vec4 vtxColor;\n"
1841                         "layout(location = 0) out vec4 fragColor;\n"
1842                         "void main (void)\n"
1843                         "{\n";
1844                         if (m_enableMinSampleShading)
1845                         {
1846                 fragmentSource <<
1847                         "    const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1848                         "    fragColor = vtxColor * (1.0 / " << (int32_t)m_rasterizationSamples << " * coveredSamples);\n";
1849                         }
1850                         else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
1851                         {
1852                 fragmentSource <<
1853                         "    fragColor = gl_FragFullyCoveredNV ? vtxColor : vec4(0.0f);\n";
1854                         }
1855                         else
1856                         {
1857                 fragmentSource <<
1858                         "    fragColor = vtxColor;\n";
1859                         }
1860                 fragmentSource <<
1861                         "}\n";
1862
1863
1864                 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1865                 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1866         }
1867
1868         {
1869                 static const char* vertexSource =
1870                         "#version 440\n"
1871                         "void main (void)\n"
1872                         "{\n"
1873                         "       const vec4 positions[4] = vec4[4](\n"
1874                         "               vec4(-1.0, -1.0, 0.0, 1.0),\n"
1875                         "               vec4(-1.0,  1.0, 0.0, 1.0),\n"
1876                         "               vec4( 1.0, -1.0, 0.0, 1.0),\n"
1877                         "               vec4( 1.0,  1.0, 0.0, 1.0)\n"
1878                         "       );\n"
1879                         "       gl_Position = positions[gl_VertexIndex];\n"
1880                         "}\n";
1881
1882
1883                 static const char* fragmentSource =
1884                         "#version 440\n"
1885                         "precision highp float;\n"
1886                         "layout(location = 0) out highp vec4 fragColor;\n"
1887                         "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
1888                         "layout(push_constant) uniform PushConstantsBlock\n"
1889                         "{\n"
1890                         "       int sampleId;\n"
1891                         "} pushConstants;\n"
1892                         "void main (void)\n"
1893                         "{\n"
1894                         "       fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
1895                         "}\n";
1896
1897                 programCollection.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
1898                 programCollection.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
1899         }
1900 }
1901
1902
1903 TestInstance* SampleMaskWithConservativeTest::createInstance (Context& context) const
1904 {
1905         return new SampleMaskWithConservativeInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enableMinSampleShading, m_minSampleShading, m_enableSampleMask, m_sampleMask,
1906                                                                                                   m_conservativeRasterizationMode, m_enablePostDepthCoverage, true, m_renderType, m_useFragmentShadingRate);
1907 }
1908
1909 // SampleMaskWithDepthTestTest
1910 #ifndef CTS_USES_VULKANSC
1911 SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext&                                     testContext,
1912                                                                                                                   const std::string&                            name,
1913                                                                                                                   const std::string&                            description,
1914                                                                                                                   const PipelineConstructionType        pipelineConstructionType,
1915                                                                                                                   const VkSampleCountFlagBits           rasterizationSamples,
1916                                                                                                                   const bool                                            enablePostDepthCoverage,
1917                                                                                                                   const bool                                            useFragmentShadingRate)
1918         : vkt::TestCase                                 (testContext, name, description)
1919         , m_pipelineConstructionType    (pipelineConstructionType)
1920         , m_rasterizationSamples                (rasterizationSamples)
1921         , m_enablePostDepthCoverage             (enablePostDepthCoverage)
1922         , m_useFragmentShadingRate              (useFragmentShadingRate)
1923 {
1924 }
1925
1926 void SampleMaskWithDepthTestTest::checkSupport (Context& context) const
1927 {
1928         if (!context.getDeviceProperties().limits.standardSampleLocations)
1929                 TCU_THROW(NotSupportedError, "standardSampleLocations required");
1930
1931         context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1932
1933         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1934
1935         if (m_useFragmentShadingRate)
1936         {
1937                 if (!context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
1938                         TCU_THROW(NotSupportedError, "fragmentShadingRateWithShaderSampleMask not supported");
1939
1940                 if (!checkFragmentShadingRateRequirements(context, m_rasterizationSamples))
1941                         TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
1942         }
1943 }
1944
1945 void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
1946 {
1947         DE_ASSERT((int)m_rasterizationSamples <= 32);
1948
1949         static const char* vertexSource =
1950                 "#version 440\n"
1951                 "layout(location = 0) in vec4 position;\n"
1952                 "layout(location = 1) in vec4 color;\n"
1953                 "layout(location = 0) out vec4 vtxColor;\n"
1954                 "out gl_PerVertex\n"
1955                 "{\n"
1956                 "    vec4 gl_Position;\n"
1957                 "};\n"
1958                 "\n"
1959                 "void main (void)\n"
1960                 "{\n"
1961                 "    gl_Position = position;\n"
1962                 "    vtxColor = color;\n"
1963                 "}\n";
1964
1965         uint32_t samplesPerFragment = m_rasterizationSamples;
1966         if (m_useFragmentShadingRate)
1967         {
1968                 // When FSR coverage is enabled the tests uses a pipeline FSR rate of {2,2},
1969                 // which means each fragment shader invocation covers 4 pixels.
1970                 samplesPerFragment *= 4;
1971
1972                 if (!m_enablePostDepthCoverage)
1973                         // For the 4 specific pixels this tests verifies, the primitive
1974                         // drawn by the test fully covers 3 of those pixels and
1975                         // partially covers 1 of them. When the fragment shader executes
1976                         // for those 4 pixels the non-PostDepthCoverage sample mask
1977                         // (the sample mask before the depth test) will only have
1978                         // 7/8 of the samples set since the last 1/8 is not even covered
1979                         // by the primitive.
1980                         samplesPerFragment -= m_rasterizationSamples / 2;
1981         }
1982
1983         std::ostringstream fragmentSource;
1984         fragmentSource <<
1985                 "#version 440\n"
1986                 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
1987                 "layout(early_fragment_tests) in;\n"
1988                 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1989                 "layout(location = 0) in vec4 vtxColor;\n"
1990                 "layout(location = 0) out vec4 fragColor;\n"
1991                 "void main (void)\n"
1992                 "{\n"
1993                 "    const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1994                 "    fragColor = vtxColor * (1.0 / " << samplesPerFragment << " * coveredSamples);\n"
1995                 "}\n";
1996
1997         programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1998         programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1999 }
2000
2001 TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
2002 {
2003         return new SampleMaskWithDepthTestInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enablePostDepthCoverage, m_useFragmentShadingRate);
2004 }
2005 #endif // CTS_USES_VULKANSC
2006
2007 // RasterizationSamplesInstance
2008
2009 RasterizationSamplesInstance::RasterizationSamplesInstance (Context&                                                                            context,
2010                                                                                                                         PipelineConstructionType                                                pipelineConstructionType,
2011                                                                                                                         VkPrimitiveTopology                                                             topology,
2012                                                                                                                         float                                                                                   pointSize,
2013                                                                                                                         const std::vector<Vertex4RGBA>&                                 vertices,
2014                                                                                                                         const VkPipelineMultisampleStateCreateInfo&             multisampleStateParams,
2015                                                                                                                         const VkPipelineColorBlendAttachmentState&              blendState,
2016                                                                                                                         const TestModeFlags                                                             modeFlags,
2017                                                                                                                         ImageBackingMode                                                                backingMode,
2018                                                                                                                         const bool                                                                              useFragmentShadingRate)
2019         : vkt::TestInstance                             (context)
2020         , m_colorFormat                                 (VK_FORMAT_R8G8B8A8_UNORM)
2021         , m_renderSize                                  (32, 32)
2022         , m_primitiveTopology                   (topology)
2023         , m_pointSize                                   (pointSize)
2024         , m_vertices                                    (vertices)
2025         , m_fullQuadVertices                    (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
2026         , m_modeFlags                                   (modeFlags)
2027         , m_useFragmentShadingRate              (useFragmentShadingRate)
2028 {
2029         if (m_modeFlags != 0)
2030         {
2031                 const bool              useDepth                        = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
2032                 const bool              useStencil                      = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
2033                 const VkFormat  depthStencilFormat      = findSupportedDepthStencilFormat(context, useDepth, useStencil);
2034
2035                 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
2036                         TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
2037
2038                 const VkPrimitiveTopology               pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
2039                 const std::vector<Vertex4RGBA>  pVertices[2] = { m_vertices, m_fullQuadVertices };
2040
2041                 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
2042                         new MultisampleRenderer(
2043                                 context, pipelineConstructionType, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil,
2044                                 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate));
2045         }
2046         else
2047         {
2048                 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
2049                         new MultisampleRenderer(
2050                                 context, pipelineConstructionType, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams,
2051                                 blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate));
2052         }
2053 }
2054
2055 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
2056 {
2057         de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
2058         return verifyImage(level->getAccess());
2059 }
2060
2061 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2062 {
2063         // Verify range of unique pixels
2064         {
2065                 const deUint32  numUniqueColors = getUniqueColorsCount(result);
2066                 const deUint32  minUniqueColors = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;
2067
2068                 tcu::TestLog& log = m_context.getTestContext().getLog();
2069
2070                 log << tcu::TestLog::Message
2071                         << "\nMin. unique colors expected: " << minUniqueColors << "\n"
2072                         << "Unique colors found: " << numUniqueColors << "\n"
2073                         << tcu::TestLog::EndMessage;
2074
2075                 if (numUniqueColors < minUniqueColors)
2076                         return tcu::TestStatus::fail("Unique colors out of expected bounds");
2077         }
2078
2079         // Verify shape of the rendered primitive (fuzzy-compare)
2080         {
2081                 const tcu::TextureFormat        tcuColorFormat  = mapVkFormat(m_colorFormat);
2082                 const tcu::TextureFormat        tcuDepthFormat  = tcu::TextureFormat();
2083                 const ColorVertexShader         vertexShader;
2084                 const ColorFragmentShader       fragmentShader  (tcuColorFormat, tcuDepthFormat);
2085                 const rr::Program                       program                 (&vertexShader, &fragmentShader);
2086                 ReferenceRenderer                       refRenderer             (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
2087                 rr::RenderState                         renderState             (refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
2088
2089                 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
2090                 {
2091                         VkPhysicalDeviceProperties deviceProperties;
2092
2093                         m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
2094
2095                         // gl_PointSize is clamped to pointSizeRange
2096                         renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
2097                 }
2098
2099                 if (m_modeFlags == 0)
2100                 {
2101                         refRenderer.colorClear(tcu::Vec4(0.0f));
2102                         refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
2103                 }
2104                 else
2105                 {
2106                         // For depth/stencil case the primitive is invisible and the surroundings are filled red.
2107                         refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
2108                         refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
2109                 }
2110
2111                 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
2112                         return tcu::TestStatus::fail("Primitive has unexpected shape");
2113         }
2114
2115         return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
2116 }
2117
2118
2119 // MinSampleShadingInstance
2120
2121 MinSampleShadingInstance::MinSampleShadingInstance (Context&                                                                    context,
2122                                                                                                         const PipelineConstructionType                          pipelineConstructionType,
2123                                                                                                         VkPrimitiveTopology                                                     topology,
2124                                                                                                         float                                                                           pointSize,
2125                                                                                                         const std::vector<Vertex4RGBA>&                         vertices,
2126                                                                                                         const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
2127                                                                                                         const VkPipelineColorBlendAttachmentState&      colorBlendState,
2128                                                                                                         ImageBackingMode                                                        backingMode,
2129                                                                                                         const bool                                                                      useFragmentShadingRate)
2130         : vkt::TestInstance                     (context)
2131         , m_pipelineConstructionType(pipelineConstructionType)
2132         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
2133         , m_renderSize                          (32, 32)
2134         , m_primitiveTopology           (topology)
2135         , m_vertices                            (vertices)
2136         , m_multisampleStateParams      (multisampleStateParams)
2137         , m_colorBlendState                     (colorBlendState)
2138         , m_backingMode                         (backingMode)
2139         , m_useFragmentShadingRate      (useFragmentShadingRate)
2140 {
2141         DE_UNREF(pointSize);
2142 }
2143
2144 tcu::TestStatus MinSampleShadingInstance::iterate (void)
2145 {
2146         de::MovePtr<tcu::TextureLevel>  noSampleshadingImage;
2147         std::vector<tcu::TextureLevel>  sampleShadedImages;
2148
2149         // Render and resolve without sample shading
2150         {
2151                 VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
2152                 multisampleStateParms.sampleShadingEnable       = VK_FALSE;
2153                 multisampleStateParms.minSampleShading          = 0.0;
2154
2155                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2156                 noSampleshadingImage  = renderer.render();
2157         }
2158
2159         // Render with test minSampleShading and collect per-sample images
2160         {
2161                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode, m_useFragmentShadingRate);
2162                 renderer.render();
2163
2164                 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
2165                 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2166                 {
2167                         sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
2168                 }
2169         }
2170
2171         // Log images
2172         {
2173                 tcu::TestLog& testLog   = m_context.getTestContext().getLog();
2174
2175                 testLog << tcu::TestLog::ImageSet("Images", "Images")
2176                                 << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
2177
2178                 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2179                 {
2180                         testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
2181                 }
2182                 testLog << tcu::TestLog::EndImageSet;
2183         }
2184
2185         return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
2186 }
2187
2188 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
2189 {
2190         const deUint32  pixelCount      = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
2191
2192         bool anyPixelCovered            = false;
2193
2194         for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
2195         {
2196                 const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
2197
2198                 if (noSampleShadingValue == 0)
2199                 {
2200                         // non-covered pixel, continue
2201                         continue;
2202                 }
2203                 else
2204                 {
2205                         anyPixelCovered = true;
2206                 }
2207
2208                 int numNotCoveredSamples = 0;
2209
2210                 std::map<deUint32, deUint32>    histogram; // map<pixel value, number of occurrences>
2211
2212                 // Collect histogram of occurrences or each pixel across all samples
2213                 for (size_t i = 0; i < sampleShadedImages.size(); ++i)
2214                 {
2215                         const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
2216
2217                         if (sampleShadedValue == 0)
2218                         {
2219                                 numNotCoveredSamples++;
2220                                 continue;
2221                         }
2222
2223                         if (histogram.find(sampleShadedValue) != histogram.end())
2224                                 histogram[sampleShadedValue]++;
2225                         else
2226                                 histogram[sampleShadedValue] = 1;
2227                 }
2228
2229                 if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
2230                 {
2231                         return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
2232                 }
2233
2234                 const int uniqueColorsCount                             = (int)histogram.size();
2235                 const int expectedUniqueSamplesCount    = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
2236
2237                 if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
2238                 {
2239                         return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
2240                 }
2241         }
2242
2243         if (!anyPixelCovered)
2244         {
2245                 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
2246         }
2247
2248         return tcu::TestStatus::pass("Got proper count of unique colors");
2249 }
2250
2251 MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance      (Context&                                                                               context,
2252                                                                                                                                          const PipelineConstructionType                                 pipelineConstructionType,
2253                                                                                                                                          VkPrimitiveTopology                                                    topology,
2254                                                                                                                                          float                                                                                  pointSize,
2255                                                                                                                                          const std::vector<Vertex4RGBA>&                                vertices,
2256                                                                                                                                          const VkPipelineMultisampleStateCreateInfo&    multisampleStateParams,
2257                                                                                                                                          const VkPipelineColorBlendAttachmentState&             blendState,
2258                                                                                                                                          ImageBackingMode                                                               backingMode,
2259                                                                                                                                          const bool                                                                             useFragmentShadingRate)
2260         : MinSampleShadingInstance      (context, pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode, useFragmentShadingRate)
2261 {
2262 }
2263
2264 tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage       (const std::vector<tcu::TextureLevel>&  sampleShadedImages,
2265                                                                                                                                                          const tcu::ConstPixelBufferAccess&             noSampleshadingImage)
2266 {
2267         const deUint32          samplesCount            = (int)sampleShadedImages.size();
2268         const deUint32          width                           = noSampleshadingImage.getWidth();
2269         const deUint32          height                          = noSampleshadingImage.getHeight();
2270         const deUint32          depth                           = noSampleshadingImage.getDepth();
2271         const tcu::UVec4        zeroPixel                       = tcu::UVec4();
2272         bool                            anyPixelCovered         = false;
2273
2274         DE_ASSERT(depth == 1);
2275         DE_UNREF(depth);
2276
2277         for (deUint32 y = 0; y < height; ++y)
2278         for (deUint32 x = 0; x < width; ++x)
2279         {
2280                 const tcu::UVec4        noSampleShadingValue    = noSampleshadingImage.getPixelUint(x, y);
2281
2282                 if (noSampleShadingValue == zeroPixel)
2283                         continue;
2284
2285                 anyPixelCovered = true;
2286                 tcu::UVec4      sampleShadingValue      = tcu::UVec4();
2287
2288                 // Collect histogram of occurrences or each pixel across all samples
2289                 for (size_t i = 0; i < samplesCount; ++i)
2290                 {
2291                         const tcu::UVec4        sampleShadedValue       = sampleShadedImages[i].getAccess().getPixelUint(x, y);
2292
2293                         sampleShadingValue += sampleShadedValue;
2294                 }
2295
2296                 sampleShadingValue = sampleShadingValue / samplesCount;
2297
2298                 if (sampleShadingValue.w() != 255)
2299                 {
2300                         return tcu::TestStatus::fail("Invalid Alpha channel value");
2301                 }
2302
2303                 if (sampleShadingValue != noSampleShadingValue)
2304                 {
2305                         return tcu::TestStatus::fail("Invalid color");
2306                 }
2307         }
2308
2309         if (!anyPixelCovered)
2310         {
2311                 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShadingDisabled");
2312         }
2313
2314         return tcu::TestStatus::pass("Got proper count of unique colors");
2315 }
2316
2317 SampleMaskInstance::SampleMaskInstance (Context&                                                                                context,
2318                                                                                 const PipelineConstructionType                                  pipelineConstructionType,
2319                                                                                 VkPrimitiveTopology                                                             topology,
2320                                                                                 float                                                                                   pointSize,
2321                                                                                 const std::vector<Vertex4RGBA>&                                 vertices,
2322                                                                                 const VkPipelineMultisampleStateCreateInfo&             multisampleStateParams,
2323                                                                                 const VkPipelineColorBlendAttachmentState&              blendState,
2324                                                                                 ImageBackingMode                                                                backingMode,
2325                                                                                 const bool                                                                              useFragmentShadingRate)
2326         : vkt::TestInstance                     (context)
2327         , m_pipelineConstructionType(pipelineConstructionType)
2328         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
2329         , m_renderSize                          (32, 32)
2330         , m_primitiveTopology           (topology)
2331         , m_vertices                            (vertices)
2332         , m_multisampleStateParams      (multisampleStateParams)
2333         , m_colorBlendState                     (blendState)
2334         , m_backingMode                         (backingMode)
2335         , m_useFragmentShadingRate      (useFragmentShadingRate)
2336 {
2337         DE_UNREF(pointSize);
2338 }
2339
2340 tcu::TestStatus SampleMaskInstance::iterate (void)
2341 {
2342         de::MovePtr<tcu::TextureLevel>                          testSampleMaskImage;
2343         de::MovePtr<tcu::TextureLevel>                          minSampleMaskImage;
2344         de::MovePtr<tcu::TextureLevel>                          maxSampleMaskImage;
2345
2346         // Render with test flags
2347         {
2348                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2349                 testSampleMaskImage = renderer.render();
2350         }
2351
2352         // Render with all flags off
2353         {
2354                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
2355                 const std::vector<VkSampleMask>                 sampleMask                      (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
2356
2357                 multisampleParams.pSampleMask = sampleMask.data();
2358
2359                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2360                 minSampleMaskImage = renderer.render();
2361         }
2362
2363         // Render with all flags on
2364         {
2365                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
2366                 const std::vector<VkSampleMask>                 sampleMask                      (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
2367
2368                 multisampleParams.pSampleMask = sampleMask.data();
2369
2370                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2371                 maxSampleMaskImage = renderer.render();
2372         }
2373
2374         return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
2375 }
2376
2377 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
2378                                                                                                  const tcu::ConstPixelBufferAccess& minSampleMaskImage,
2379                                                                                                  const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
2380 {
2381         const deUint32  testColorCount  = getUniqueColorsCount(testSampleMaskImage);
2382         const deUint32  minColorCount   = getUniqueColorsCount(minSampleMaskImage);
2383         const deUint32  maxColorCount   = getUniqueColorsCount(maxSampleMaskImage);
2384
2385         tcu::TestLog& log = m_context.getTestContext().getLog();
2386
2387         log << tcu::TestLog::Message
2388                 << "\nColors found: " << testColorCount << "\n"
2389                 << "Min. colors expected: " << minColorCount << "\n"
2390                 << "Max. colors expected: " << maxColorCount << "\n"
2391                 << tcu::TestLog::EndMessage;
2392
2393         if (minColorCount > testColorCount || testColorCount > maxColorCount)
2394                 return tcu::TestStatus::fail("Unique colors out of expected bounds");
2395         else
2396                 return tcu::TestStatus::pass("Unique colors within expected bounds");
2397 }
2398 #ifndef CTS_USES_VULKANSC
2399 tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
2400 {
2401         const VkSampleCountFlagBits samples[] =
2402         {
2403                 VK_SAMPLE_COUNT_1_BIT,
2404                 VK_SAMPLE_COUNT_2_BIT,
2405                 VK_SAMPLE_COUNT_4_BIT,
2406                 VK_SAMPLE_COUNT_8_BIT,
2407                 VK_SAMPLE_COUNT_16_BIT,
2408                 VK_SAMPLE_COUNT_32_BIT,
2409                 VK_SAMPLE_COUNT_64_BIT
2410         };
2411
2412         const Vertex4RGBA vertexData[3] =
2413         {
2414                 {
2415                         tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
2416                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2417                 },
2418                 {
2419                         tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
2420                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2421                 },
2422                 {
2423                         tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
2424                         tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2425                 }
2426         };
2427
2428         const std::vector<Vertex4RGBA>  vertices                        (vertexData, vertexData + 3);
2429         deUint32                                                prevUniqueColors        = 2;
2430         int                                                             renderCount                     = 0;
2431
2432         // Do not render with 1 sample (start with samplesNdx = 1).
2433         for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2434         {
2435                 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
2436                         continue;
2437
2438                 if (params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, samples[samplesNdx]))
2439                         continue;
2440
2441                 const VkPipelineMultisampleStateCreateInfo multisampleStateParams
2442                 {
2443                         VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
2444                         DE_NULL,                                                                                                        // const void*                                                          pNext;
2445                         0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
2446                         samples[samplesNdx],                                                                            // VkSampleCountFlagBits                                        rasterizationSamples;
2447                         false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
2448                         0.0f,                                                                                                           // float                                                                        minSampleShading;
2449                         DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
2450                         false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
2451                         false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
2452                 };
2453
2454                 MultisampleRenderer                             renderer                (context, params.pipelineConstructionType, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode, params.useFragmentShadingRate);
2455                 de::MovePtr<tcu::TextureLevel>  result                  = renderer.render();
2456                 const deUint32                                  uniqueColors    = getUniqueColorsCount(result->getAccess());
2457
2458                 renderCount++;
2459
2460                 if (prevUniqueColors > uniqueColors)
2461                 {
2462                         std::ostringstream message;
2463
2464                         message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
2465                         return tcu::TestStatus::fail(message.str());
2466                 }
2467
2468                 prevUniqueColors = uniqueColors;
2469         }
2470
2471         if (renderCount == 0)
2472         {
2473                 if (params.useFragmentShadingRate && !context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
2474                         TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate is unsupported");
2475                 TCU_THROW(NotSupportedError, "Multisampling is unsupported");
2476         }
2477
2478         return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
2479 }
2480 #endif // CTS_USES_VULKANSC
2481
2482 // AlphaToOneInstance
2483
2484 AlphaToOneInstance::AlphaToOneInstance (Context&                                                                        context,
2485                                                                                 const PipelineConstructionType                          pipelineConstructionType,
2486                                                                                 VkPrimitiveTopology                                                     topology,
2487                                                                                 const std::vector<Vertex4RGBA>&                         vertices,
2488                                                                                 const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
2489                                                                                 const VkPipelineColorBlendAttachmentState&      blendState,
2490                                                                                 ImageBackingMode                                                        backingMode,
2491                                                                                 const bool                                                                      useFragmentShadingRate)
2492         : vkt::TestInstance                     (context)
2493         , m_pipelineConstructionType(pipelineConstructionType)
2494         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
2495         , m_renderSize                          (32, 32)
2496         , m_primitiveTopology           (topology)
2497         , m_vertices                            (vertices)
2498         , m_multisampleStateParams      (multisampleStateParams)
2499         , m_colorBlendState                     (blendState)
2500         , m_backingMode                         (backingMode)
2501         , m_useFragmentShadingRate      (useFragmentShadingRate)
2502 {
2503 }
2504
2505 tcu::TestStatus AlphaToOneInstance::iterate     (void)
2506 {
2507         DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
2508         DE_ASSERT(m_colorBlendState.blendEnable);
2509
2510         de::MovePtr<tcu::TextureLevel>  alphaOneImage;
2511         de::MovePtr<tcu::TextureLevel>  noAlphaOneImage;
2512
2513         RenderType renderType = m_multisampleStateParams.rasterizationSamples == vk::VK_SAMPLE_COUNT_1_BIT ? RENDER_TYPE_SINGLE_SAMPLE : RENDER_TYPE_RESOLVE;
2514
2515         // Render with blend enabled and alpha to one on
2516         {
2517                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate);
2518                 alphaOneImage = renderer.render();
2519         }
2520
2521         // Render with blend enabled and alpha to one off
2522         {
2523                 VkPipelineMultisampleStateCreateInfo    multisampleParams       = m_multisampleStateParams;
2524                 multisampleParams.alphaToOneEnable = false;
2525
2526                 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate);
2527                 noAlphaOneImage = renderer.render();
2528         }
2529
2530         return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
2531 }
2532
2533 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess&     alphaOneImage,
2534                                                                                                  const tcu::ConstPixelBufferAccess&     noAlphaOneImage)
2535 {
2536         for (int y = 0; y < m_renderSize.y(); y++)
2537         {
2538                 for (int x = 0; x < m_renderSize.x(); x++)
2539                 {
2540                         if (alphaOneImage.getPixel(x, y).w() != 1.0)
2541                         {
2542                                 std::ostringstream message;
2543                                 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " doesn't have alpha set to 1";
2544                                 return tcu::TestStatus::fail(message.str());
2545                         }
2546
2547                         if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
2548                         {
2549                                 std::ostringstream message;
2550                                 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
2551                                 return tcu::TestStatus::fail(message.str());
2552                         }
2553                 }
2554         }
2555
2556         return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
2557 }
2558
2559
2560 // AlphaToCoverageInstance
2561
2562 AlphaToCoverageInstance::AlphaToCoverageInstance (Context&                                                                              context,
2563                                                                                                   const PipelineConstructionType                                pipelineConstructionType,
2564                                                                                                   VkPrimitiveTopology                                                   topology,
2565                                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
2566                                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
2567                                                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
2568                                                                                                   GeometryType                                                                  geometryType,
2569                                                                                                   ImageBackingMode                                                              backingMode,
2570                                                                                                   const bool                                                                    useFragmentShadingRate)
2571         : vkt::TestInstance                     (context)
2572         , m_pipelineConstructionType(pipelineConstructionType)
2573         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
2574         , m_renderSize                          (32, 32)
2575         , m_primitiveTopology           (topology)
2576         , m_vertices                            (vertices)
2577         , m_multisampleStateParams      (multisampleStateParams)
2578         , m_colorBlendState                     (blendState)
2579         , m_geometryType                        (geometryType)
2580         , m_backingMode                         (backingMode)
2581         , m_useFragmentShadingRate      (useFragmentShadingRate)
2582 {
2583 }
2584
2585 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
2586 {
2587         DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2588
2589         de::MovePtr<tcu::TextureLevel>  result;
2590         MultisampleRenderer                             renderer        (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2591
2592         result = renderer.render();
2593
2594         return verifyImage(result->getAccess());
2595 }
2596
2597 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess&        result)
2598 {
2599         float maxColorValue;
2600
2601         switch (m_geometryType)
2602         {
2603                 case GEOMETRY_TYPE_OPAQUE_QUAD:
2604                         maxColorValue = 1.01f;
2605                         break;
2606
2607                 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
2608                         maxColorValue = 0.52f;
2609                         break;
2610
2611                 case GEOMETRY_TYPE_INVISIBLE_QUAD:
2612                         maxColorValue = 0.01f;
2613                         break;
2614
2615                 default:
2616                         maxColorValue = 0.0f;
2617                         DE_ASSERT(false);
2618         }
2619
2620         for (int y = 0; y < m_renderSize.y(); y++)
2621         {
2622                 for (int x = 0; x < m_renderSize.x(); x++)
2623                 {
2624                         if (result.getPixel(x, y).x() > maxColorValue)
2625                         {
2626                                 std::ostringstream message;
2627                                 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
2628                                 return tcu::TestStatus::fail(message.str());
2629                         }
2630                 }
2631         }
2632
2633         return tcu::TestStatus::pass("Image matches reference value");
2634 }
2635
2636 // AlphaToCoverageNoColorAttachmentInstance
2637
2638 AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context&                                                                    context,
2639                                                                                                                                                                         const PipelineConstructionType                          pipelineConstructionType,
2640                                                                                                                                                                         VkPrimitiveTopology                                                     topology,
2641                                                                                                                                                                         const std::vector<Vertex4RGBA>&                         vertices,
2642                                                                                                                                                                         const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
2643                                                                                                                                                                         const VkPipelineColorBlendAttachmentState&      blendState,
2644                                                                                                                                                                         GeometryType                                                            geometryType,
2645                                                                                                                                                                         ImageBackingMode                                                        backingMode,
2646                                                                                                                                                                         const bool                                                                      useFragmentShadingRate)
2647         : vkt::TestInstance                     (context)
2648         , m_pipelineConstructionType(pipelineConstructionType)
2649         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
2650         , m_depthStencilFormat          (VK_FORMAT_D16_UNORM)
2651         , m_renderSize                          (32, 32)
2652         , m_primitiveTopology           (topology)
2653         , m_vertices                            (vertices)
2654         , m_multisampleStateParams      (multisampleStateParams)
2655         , m_colorBlendState                     (blendState)
2656         , m_geometryType                        (geometryType)
2657         , m_backingMode                         (backingMode)
2658         , m_useFragmentShadingRate      (useFragmentShadingRate)
2659 {
2660 }
2661
2662 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
2663 {
2664         DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2665
2666         de::MovePtr<tcu::TextureLevel>  result;
2667         MultisampleRenderer                             renderer        (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, m_useFragmentShadingRate, 1.0f);
2668
2669         result = renderer.render();
2670
2671         return verifyImage(result->getAccess());
2672 }
2673
2674 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&       result)
2675 {
2676         for (int y = 0; y < m_renderSize.y(); y++)
2677         {
2678                 for (int x = 0; x < m_renderSize.x(); x++)
2679                 {
2680                         // Expect full red for each pixel. Fail if clear color is showing.
2681                         if (result.getPixel(x, y).x() < 1.0f)
2682                         {
2683                                 // Log result image when failing.
2684                                 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2685
2686                                 return tcu::TestStatus::fail("Fail");
2687                         }
2688                 }
2689         }
2690
2691         return tcu::TestStatus::pass("Pass");
2692 }
2693
2694 // AlphaToCoverageColorUnusedAttachmentInstance
2695
2696 AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context&                                                                    context,
2697                                                                                                                                                                                         const PipelineConstructionType                          pipelineConstructionType,
2698                                                                                                                                                                                         VkPrimitiveTopology                                                     topology,
2699                                                                                                                                                                                         const std::vector<Vertex4RGBA>&                         vertices,
2700                                                                                                                                                                                         const VkPipelineMultisampleStateCreateInfo&     multisampleStateParams,
2701                                                                                                                                                                                         const VkPipelineColorBlendAttachmentState&      blendState,
2702                                                                                                                                                                                         GeometryType                                                            geometryType,
2703                                                                                                                                                                                         ImageBackingMode                                                        backingMode,
2704                                                                                                                                                                                         const bool                                                                      useFragmentShadingRate)
2705         : vkt::TestInstance                             (context)
2706         , m_pipelineConstructionType    (pipelineConstructionType)
2707         , m_colorFormat                                 (VK_FORMAT_R5G6B5_UNORM_PACK16)
2708         , m_renderSize                                  (32, 32)
2709         , m_primitiveTopology                   (topology)
2710         , m_vertices                                    (vertices)
2711         , m_multisampleStateParams              (multisampleStateParams)
2712         , m_colorBlendState                             (blendState)
2713         , m_geometryType                                (geometryType)
2714         , m_backingMode                                 (backingMode)
2715         , m_useFragmentShadingRate              (useFragmentShadingRate)
2716 {
2717 }
2718
2719 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
2720 {
2721         DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2722
2723         de::MovePtr<tcu::TextureLevel>  result;
2724         MultisampleRenderer                             renderer        (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode, m_useFragmentShadingRate);
2725
2726         result = renderer.render();
2727
2728         return verifyImage(result->getAccess());
2729 }
2730
2731 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess&   result)
2732 {
2733         for (int y = 0; y < m_renderSize.y(); y++)
2734         {
2735                 for (int x = 0; x < m_renderSize.x(); x++)
2736                 {
2737                         // Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
2738                         // The coverage should still be affected by the alpha written to location 0.
2739                         if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
2740                                 || (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
2741                         {
2742                                 // Log result image when failing.
2743                                 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2744
2745                                 return tcu::TestStatus::fail("Fail");
2746                         }
2747                 }
2748         }
2749
2750         return tcu::TestStatus::pass("Pass");
2751 }
2752
2753 // SampleMaskWithConservativeInstance
2754
2755 SampleMaskWithConservativeInstance::SampleMaskWithConservativeInstance (Context&                                                                        context,
2756                                                                                                                                                 const PipelineConstructionType                          pipelineConstructionType,
2757                                                                                                                                                 const VkSampleCountFlagBits                                     rasterizationSamples,
2758                                                                                                                                                 const bool                                                                      enableMinSampleShading,
2759                                                                                                                                                 const float                                                                     minSampleShading,
2760                                                                                                                                                 const bool                                                                      enableSampleMask,
2761                                                                                                                                                 const VkSampleMask                                                      sampleMask,
2762                                                                                                                                                 const VkConservativeRasterizationModeEXT        conservativeRasterizationMode,
2763                                                                                                                                                 const bool                                                                      enablePostDepthCoverage,
2764                                                                                                                                                 const bool                                                                      enableFullyCoveredEXT,
2765                                                                                                                                                 const RenderType                                                        renderType,
2766                                                                                                                                                 const bool                                                                      useFragmentShadingRate)
2767         : vkt::TestInstance                                                             (context)
2768         , m_pipelineConstructionType                                    (pipelineConstructionType)
2769         , m_rasterizationSamples                                                (rasterizationSamples)
2770         , m_enablePostDepthCoverage                                             (enablePostDepthCoverage)
2771         , m_enableFullyCoveredEXT                                               (enableFullyCoveredEXT)
2772         , m_colorFormat                                                                 (VK_FORMAT_R8G8B8A8_UNORM)
2773         , m_depthStencilFormat                                                  (VK_FORMAT_D16_UNORM)
2774         , m_renderSize                                                                  (tcu::IVec2(10, 10))
2775         , m_useDepth                                                                    (true)
2776         , m_useStencil                                                                  (false)
2777         , m_useConservative                                                             (true)
2778         , m_useFragmentShadingRate                                              (useFragmentShadingRate)
2779         , m_conservativeRasterizationMode                               (conservativeRasterizationMode)
2780         , m_topology                                                                    (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2781         , m_renderColor                                                                 (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
2782         , m_depthClearValue                                                             (0.5f)
2783         , m_vertices                                                                    (generateVertices())
2784         , m_enableSampleMask                                                    (enableSampleMask)
2785         , m_sampleMask                                                                  (std::vector<VkSampleMask>{sampleMask})
2786         , m_enableMinSampleShading                                              (enableMinSampleShading)
2787         , m_minSampleShading                                                    (minSampleShading)
2788         , m_multisampleStateParams                                              (getMultisampleState(rasterizationSamples, enableMinSampleShading, minSampleShading, enableSampleMask))
2789         , m_rasterizationConservativeStateCreateInfo    (getRasterizationConservativeStateCreateInfo(conservativeRasterizationMode))
2790         , m_blendState                                                                  (getDefaultColorBlendAttachmentState())
2791         , m_renderType                                                                  (renderType)
2792         , m_imageBackingMode                                                    (IMAGE_BACKING_MODE_REGULAR)
2793 {
2794 }
2795
2796 tcu::TestStatus SampleMaskWithConservativeInstance::iterate (void)
2797 {
2798
2799         de::MovePtr<tcu::TextureLevel>  noSampleshadingImage;
2800         std::vector<tcu::TextureLevel>  sampleShadedImages;
2801
2802         {
2803                 MultisampleRenderer renderer(m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, m_useConservative, m_useFragmentShadingRate, 1u,
2804                         &m_topology, &m_vertices, m_multisampleStateParams, m_blendState, m_rasterizationConservativeStateCreateInfo, RENDER_TYPE_RESOLVE, m_imageBackingMode, m_depthClearValue);
2805                 noSampleshadingImage = renderer.render();
2806         }
2807
2808         {
2809                 const VkPipelineColorBlendAttachmentState colorBlendState =
2810                 {
2811                         false,                                                                                                          // VkBool32                                     blendEnable;
2812                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcColorBlendFactor;
2813                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstColorBlendFactor;
2814                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            colorBlendOp;
2815                         VK_BLEND_FACTOR_ONE,                                                                            // VkBlendFactor                        srcAlphaBlendFactor;
2816                         VK_BLEND_FACTOR_ZERO,                                                                           // VkBlendFactor                        dstAlphaBlendFactor;
2817                         VK_BLEND_OP_ADD,                                                                                        // VkBlendOp                            alphaBlendOp;
2818                         VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |           // VkColorComponentFlags        colorWriteMask;
2819                                 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
2820                 };
2821
2822                 MultisampleRenderer mRenderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_vertices, m_multisampleStateParams, colorBlendState, RENDER_TYPE_COPY_SAMPLES, IMAGE_BACKING_MODE_REGULAR, m_useFragmentShadingRate);
2823                 mRenderer.render();
2824
2825                 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
2826                 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2827                 {
2828                         sampleShadedImages[sampleId] = *mRenderer.getSingleSampledImage(sampleId);
2829                 }
2830
2831         }
2832
2833         return verifyImage(sampleShadedImages, noSampleshadingImage->getAccess());
2834 }
2835
2836 VkPipelineMultisampleStateCreateInfo SampleMaskWithConservativeInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples, const bool enableMinSampleShading, const float minSampleShading, const bool enableSampleMask)
2837 {
2838         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2839         {
2840                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
2841                 DE_NULL,                                                                                                        // const void*                                                          pNext;
2842                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
2843                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
2844                 enableMinSampleShading ? VK_TRUE : VK_FALSE,                            // VkBool32                                                                     sampleShadingEnable;
2845                 enableMinSampleShading ? minSampleShading : 0.0f,                       // float                                                                        minSampleShading;
2846                 enableSampleMask ? m_sampleMask.data() : DE_NULL,                       // const VkSampleMask*                                          pSampleMask;
2847                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
2848                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
2849         };
2850
2851         return multisampleStateParams;
2852 }
2853
2854 VkPipelineRasterizationConservativeStateCreateInfoEXT  SampleMaskWithConservativeInstance::getRasterizationConservativeStateCreateInfo(const VkConservativeRasterizationModeEXT conservativeRasterizationMode)
2855 {
2856         const VkPipelineRasterizationConservativeStateCreateInfoEXT     rasterizationConservativeStateCreateInfo =
2857                 {
2858                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT,    //  VkStructureType                                                                                     sType;
2859                         DE_NULL,                                                                                                                                                //  const void*                                                                                         pNext;
2860                         (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0,                                              //  VkPipelineRasterizationConservativeStateCreateFlagsEXT      flags;
2861                         conservativeRasterizationMode,                                                                                                  //  VkConservativeRasterizationModeEXT                                          conservativeRasterizationMode;
2862                         0.0f                                                                                                                                                    //  float                                                                                                       extraPrimitiveOverestimationSize;
2863                 };
2864
2865         return rasterizationConservativeStateCreateInfo;
2866 }
2867
2868 std::vector<Vertex4RGBA> SampleMaskWithConservativeInstance::generateVertices (void)
2869 {
2870         std::vector<Vertex4RGBA> vertices;
2871
2872         {
2873                 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
2874                 vertices.push_back(vertexInput);
2875         }
2876         {
2877                 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
2878                 vertices.push_back(vertexInput);
2879         }
2880         {
2881                 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 0.0f, 1.0f), m_renderColor };
2882                 vertices.push_back(vertexInput);
2883         }
2884
2885         return vertices;
2886 }
2887
2888 tcu::TestStatus SampleMaskWithConservativeInstance::verifyImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& result)
2889 {
2890         bool                    pass    = true;
2891         const int               width   = result.getWidth();
2892         const int               height  = result.getHeight();
2893         tcu::TestLog&   log             = m_context.getTestContext().getLog();
2894
2895         const deUint32          samplesCount            = (int)sampleShadedImages.size();
2896
2897         for (size_t i = 0; i < samplesCount; ++i)
2898         {
2899                 const tcu::ConstPixelBufferAccess &s = sampleShadedImages[i].getAccess();
2900
2901                 log << tcu::TestLog::ImageSet("Per sample image", "Per sampe image")
2902                         << tcu::TestLog::Image("Layer", "Layer", s)
2903                         << tcu::TestLog::EndImageSet;
2904         }
2905
2906         // Leave sample count intact (return 1) if multiplication by minSampleShading won't exceed base 2
2907         // otherwise round up to the nearest power of 2
2908         auto sampleCountDivider = [](float x) {
2909                 float power = 1.0;
2910                 while (power < x)
2911                 {
2912                         power *= 2;
2913                 }
2914                 return power;
2915         };
2916
2917         DE_ASSERT(width == 10);
2918         DE_ASSERT(height == 10);
2919
2920         const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
2921         std::vector<std::pair<int, int>> fullyCoveredPixelsCoordinateSet;
2922
2923         // Generating set of pixel coordinate values covered by the triangle
2924         if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
2925         {
2926                 for (int i = 0; i < width; i++)
2927                 {
2928                         for (int j = 0; j < height; j++)
2929                         {
2930                                 // Rasterization will cover half of the triangle plus 1 pixel edge due to the overeestimation
2931                                 if (i < 5 && i + j < 11)
2932                                         fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2933                         }
2934                 }
2935         }
2936         else
2937         {
2938                 if (m_useFragmentShadingRate && !m_enableMinSampleShading)
2939                 {
2940                         // When m_enableMinSampleShading is not enabled shader uses gl_FragFullyCoveredNV.
2941                         // Additionaly when FSR coverage is enabled the tests uses a pipeline FSR rate of { 2,2 }
2942                         // and as a result rasterization will cover only four pixels due to the underestimation.
2943                         for (int i = 2; i < 4; i++)
2944                                 for (int j = 2; j < 4; j++)
2945                                         fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2946                 }
2947                 else
2948                 {
2949                         for (int i = 1; i < width; i++)
2950                         {
2951                                 for (int j = 1; j < height; j++)
2952                                 {
2953                                         // Rasterization will cover half of the triangle minus 1 pixel edge due to the underestimation
2954                                         if (i < 5 && i + j < 8)
2955                                                 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2956                                 }
2957                         }
2958                 }
2959         }
2960
2961         for (int x = 0; x < width; ++x)
2962                 for (int y = 0; y < height; ++y)
2963                 {
2964                         const tcu::Vec4 resultPixel = result.getPixel(x, y);
2965
2966                         if (std::find(fullyCoveredPixelsCoordinateSet.begin(), fullyCoveredPixelsCoordinateSet.end(), std::make_pair(x, y)) != fullyCoveredPixelsCoordinateSet.end())
2967                         {
2968                                 if (m_enableMinSampleShading)
2969                                 {
2970                                         tcu::UVec4      sampleShadingValue = tcu::UVec4();
2971                                         for (size_t i = 0; i < samplesCount; ++i)
2972                                         {
2973                                                 const tcu::UVec4        sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y);
2974
2975                                                 sampleShadingValue += sampleShadedValue;
2976                                         }
2977
2978                                         //Calculate coverage of a single sample Image based on accumulated value from the whole set
2979                                         int sampleCoverageValue = sampleShadingValue.w() / samplesCount;
2980                                         //Calculates an estimated coverage value based on the number of samples and the minimumSampleShading
2981                                         int expectedCovergaveValue = (int)(255.0 / sampleCountDivider((float)m_rasterizationSamples * m_minSampleShading)) + 1;
2982
2983                                         //The specification allows for larger sample count than minimum value, however resulted coverage should never be lower than minimum
2984                                         if (sampleCoverageValue > expectedCovergaveValue)
2985                                         {
2986                                                 log << tcu::TestLog::Message << "Coverage value " << sampleCoverageValue <<  " greather than expected: " << expectedCovergaveValue << tcu::TestLog::EndMessage;
2987
2988                                                 pass = false;
2989                                         }
2990                                 }
2991                                 else if (m_enableSampleMask)
2992                                 {
2993                                         // Sample mask with all bits on will not affect fragment coverage
2994                                         if (m_sampleMask[0] == 0xFFFFFFFF)
2995                                         {
2996                                                 if (resultPixel != m_renderColor)
2997                                                 {
2998                                                         log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2999                                                                 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
3000
3001                                                         pass = false;
3002                                                 }
3003                                         }
3004                                         // Sample mask with half bits off will reduce sample coverage by half
3005                                         else if (m_sampleMask[0] == 0xAAAAAAAA)
3006                                         {
3007
3008                                                 const tcu::Vec4 renderColorHalfOpacity(0.0f, 0.5f, 0.0f, 0.5f);
3009                                                 const float             threshold = 0.02f;
3010
3011                                                 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3012                                                 {
3013                                                         if ((renderColorHalfOpacity[componentNdx] != 0.0f && resultPixel[componentNdx] <= (renderColorHalfOpacity[componentNdx] - threshold))
3014                                                                 || resultPixel[componentNdx] >= (renderColorHalfOpacity[componentNdx] + threshold))
3015                                                         {
3016                                                                 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3017                                                                         << " Reference: " << renderColorHalfOpacity << " +/- " << threshold << tcu::TestLog::EndMessage;
3018
3019                                                                 pass = false;
3020                                                         }
3021                                                 }
3022                                         }
3023                                         // Sample mask with all bits off will cause all fragment to failed opacity test
3024                                         else if (m_sampleMask[0] == 0x00000000)
3025                                         {
3026                                                 if (resultPixel != clearColor)
3027                                                 {
3028                                                         log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3029                                                                 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3030
3031                                                         pass = false;
3032                                                 }
3033                                         }
3034                                         else
3035                                         {
3036                                                 log << tcu::TestLog::Message << "Unexpected sample mask value" << tcu::TestLog::EndMessage;
3037
3038                                                 pass = false;
3039                                         }
3040                                 }
3041                                 else
3042                                 {
3043                                         if (resultPixel != m_renderColor)
3044                                         {
3045                                                 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3046                                                         << " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
3047
3048                                                 pass = false;
3049                                         }
3050                                 }
3051                         }
3052                         else
3053                         {
3054                                 if (resultPixel != clearColor)
3055                                 {
3056                                         log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3057                                                 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3058
3059                                         pass = false;
3060                                 }
3061                         }
3062                 }
3063
3064         if (pass)
3065                 return tcu::TestStatus::pass("Passed");
3066         else
3067         {
3068                 log << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3069                         << tcu::TestLog::Image("Layer", "Layer", result)
3070                         << tcu::TestLog::EndImageSet;
3071
3072                 return tcu::TestStatus::fail("Failed");
3073         }
3074
3075 }
3076
3077 // SampleMaskWithDepthTestInstance
3078 #ifndef CTS_USES_VULKANSC
3079 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context&                                                      context,
3080                                                                                                                                   const PipelineConstructionType        pipelineConstructionType,
3081                                                                                                                                   const VkSampleCountFlagBits           rasterizationSamples,
3082                                                                                                                                   const bool                                            enablePostDepthCoverage,
3083                                                                                                                                   const bool                                            useFragmentShadingRate)
3084         : vkt::TestInstance                     (context)
3085         , m_pipelineConstructionType(pipelineConstructionType)
3086         , m_rasterizationSamples        (rasterizationSamples)
3087         , m_enablePostDepthCoverage     (enablePostDepthCoverage)
3088         , m_colorFormat                         (VK_FORMAT_R8G8B8A8_UNORM)
3089         , m_depthStencilFormat          (VK_FORMAT_D16_UNORM)
3090         , m_renderSize                          (tcu::IVec2(3, 3))
3091         , m_useDepth                            (true)
3092         , m_useStencil                          (false)
3093         , m_topology                            (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3094         , m_renderColor                         (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
3095         , m_vertices                            (generateVertices())
3096         , m_multisampleStateParams      (getMultisampleState(rasterizationSamples))
3097         , m_blendState                          (getDefaultColorBlendAttachmentState())
3098         , m_renderType                          (RENDER_TYPE_RESOLVE)
3099         , m_imageBackingMode            (IMAGE_BACKING_MODE_REGULAR)
3100         , m_depthClearValue                     (0.667f)
3101         , m_useFragmentShadingRate      (useFragmentShadingRate)
3102 {
3103         m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT]      = SampleCoverage(1u, 1u);       // !< Sample coverage of the diagonally halved pixel,
3104         m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT]      = SampleCoverage(2u, 2u);       // !< with max possible subPixelPrecisionBits threshold
3105         m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT]      = SampleCoverage(2u, 6u);       // !<
3106         m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT]     = SampleCoverage(6u, 11u);      // !<
3107 }
3108
3109 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
3110 {
3111         de::MovePtr<tcu::TextureLevel>  result;
3112
3113         MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
3114                                                                   &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_useFragmentShadingRate, m_depthClearValue);
3115         result = renderer.render();
3116
3117         return verifyImage(result->getAccess());
3118 }
3119
3120 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
3121 {
3122         const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
3123         {
3124                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,       // VkStructureType                                                      sType;
3125                 DE_NULL,                                                                                                        // const void*                                                          pNext;
3126                 0u,                                                                                                                     // VkPipelineMultisampleStateCreateFlags        flags;
3127                 rasterizationSamples,                                                                           // VkSampleCountFlagBits                                        rasterizationSamples;
3128                 false,                                                                                                          // VkBool32                                                                     sampleShadingEnable;
3129                 0.0f,                                                                                                           // float                                                                        minSampleShading;
3130                 DE_NULL,                                                                                                        // const VkSampleMask*                                          pSampleMask;
3131                 false,                                                                                                          // VkBool32                                                                     alphaToCoverageEnable;
3132                 false                                                                                                           // VkBool32                                                                     alphaToOneEnable;
3133         };
3134
3135         return multisampleStateParams;
3136 }
3137
3138 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
3139 {
3140         std::vector<Vertex4RGBA> vertices;
3141
3142         {
3143                 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
3144                 vertices.push_back(vertexInput);
3145         }
3146         {
3147                 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
3148                 vertices.push_back(vertexInput);
3149         }
3150         {
3151                 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f,  1.0f, 1.0f, 1.0f), m_renderColor };
3152                 vertices.push_back(vertexInput);
3153         }
3154
3155         return vertices;
3156 }
3157
3158 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
3159 {
3160         bool                    pass    = true;
3161         const int               width   = result.getWidth();
3162         const int               height  = result.getHeight();
3163         tcu::TestLog&   log             = m_context.getTestContext().getLog();
3164
3165         DE_ASSERT(width == 3);
3166         DE_ASSERT(height == 3);
3167
3168         const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
3169
3170         for (int x = 0; x < width; ++x)
3171         for (int y = 0; y < height; ++y)
3172         {
3173                 const tcu::Vec4 resultPixel = result.getPixel(x, y);
3174
3175                 if (x + y == 0)
3176                 {
3177                         const float             threshold               = 0.02f;
3178                         tcu::Vec4               expectedPixel   = m_renderColor;
3179
3180                         if (m_useFragmentShadingRate && m_enablePostDepthCoverage)
3181                         {
3182                                 // The fragment shader for this test outputs a fragment value that
3183                                 // is based off gl_SampleMaskIn. For the FSR case that sample mask
3184                                 // applies to 4 pixels, rather than the usual 1 pixel per fragment
3185                                 // shader invocation. Those 4 pixels represent:
3186                                 //   a) The fully covered pixel (this "x + y == 0" case)
3187                                 //   b) The two partially covered pixels (the "x + y == 1" case below)
3188                                 //   c) The non-covered pixel (the "else" case below)
3189                                 //
3190                                 // For the PostDepthCoverage case, the gl_SampleMaskIn represents
3191                                 // coverage after the depth test, so it has roughly 50% of the bits
3192                                 // set. This means that the expected result for this case (a)
3193                                 // will not be the "m_renderColor" but ~50% of the m_renderColor.
3194                                 expectedPixel = expectedPixel * tcu::Vec4(0.5f);
3195                         }
3196
3197                         bool                    localPass               = true;
3198                         for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3199                         {
3200                                 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= expectedPixel[componentNdx] * (1.0f - threshold)
3201                                         || resultPixel[componentNdx] >= expectedPixel[componentNdx] * (1.0f + threshold)))
3202                                         localPass = false;
3203                         }
3204
3205                         if (!localPass)
3206                         {
3207                                 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3208                                         << " Reference range ( " << expectedPixel * (1.0f - threshold) << " ; " << expectedPixel * (1.0f + threshold) << " )" << tcu::TestLog::EndMessage;
3209                                 pass = false;
3210                         }
3211                 }
3212                 else if (x + y == 1)
3213                 {
3214                         const float             threshold       = 0.02f;
3215                         float                   minCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples;
3216                         float                   maxCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples;
3217
3218                         // default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
3219                         // post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
3220
3221                         if (m_enablePostDepthCoverage)
3222                         {
3223                                 minCoverage *= minCoverage;
3224                                 maxCoverage *= maxCoverage;
3225                         }
3226
3227                         bool                    localPass       = true;
3228                         for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3229                         {
3230                                 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
3231                                                                                                                         || resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
3232                                         localPass = false;
3233                         }
3234
3235                         if (!localPass)
3236                         {
3237                                 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3238                                         << " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
3239                                 pass = false;
3240                         }
3241                 }
3242                 else
3243                 {
3244                         if (resultPixel != clearColor)
3245                         {
3246                                 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3247                                         << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3248                                 pass = false;
3249                         }
3250                 }
3251         }
3252
3253         if (pass)
3254                 return tcu::TestStatus::pass("Passed");
3255         else
3256                 return tcu::TestStatus::fail("Failed");
3257 }
3258 #endif // CTS_USES_VULKANSC
3259 // MultisampleRenderer
3260
3261 MultisampleRenderer::MultisampleRenderer (Context&                                                                              context,
3262                                                                                   const PipelineConstructionType                                pipelineConstructionType,
3263                                                                                   const VkFormat                                                                colorFormat,
3264                                                                                   const tcu::IVec2&                                                             renderSize,
3265                                                                                   const VkPrimitiveTopology                                             topology,
3266                                                                                   const std::vector<Vertex4RGBA>&                               vertices,
3267                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
3268                                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
3269                                                                                   const RenderType                                                              renderType,
3270                                                                                   const ImageBackingMode                                                backingMode,
3271                                                                                   const bool                                                                    useFragmentShadingRate)
3272         : m_context                                     (context)
3273         , m_pipelineConstructionType(pipelineConstructionType)
3274         , m_bindSemaphore                       (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3275         , m_colorFormat                         (colorFormat)
3276         , m_depthStencilFormat          (VK_FORMAT_UNDEFINED)
3277         , m_renderSize                          (renderSize)
3278         , m_useDepth                            (false)
3279         , m_useStencil                          (false)
3280         , m_useConservative                     (false)
3281         , m_multisampleStateParams      (multisampleStateParams)
3282         , m_colorBlendState                     (blendState)
3283         , m_rasterizationConservativeStateCreateInfo ()
3284         , m_renderType                          (renderType)
3285         , m_backingMode                         (backingMode)
3286         , m_depthClearValue                     (1.0f)
3287         , m_useFragmentShadingRate      (useFragmentShadingRate)
3288 {
3289         initialize(context, 1u, &topology, &vertices);
3290 }
3291
3292 MultisampleRenderer::MultisampleRenderer (Context&                                                                              context,
3293                                                                                   const PipelineConstructionType                                pipelineConstructionType,
3294                                                                                   const VkFormat                                                                colorFormat,
3295                                                                                   const VkFormat                                                                depthStencilFormat,
3296                                                                                   const tcu::IVec2&                                                             renderSize,
3297                                                                                   const bool                                                                    useDepth,
3298                                                                                   const bool                                                                    useStencil,
3299                                                                                   const deUint32                                                                numTopologies,
3300                                                                                   const VkPrimitiveTopology*                                    pTopology,
3301                                                                                   const std::vector<Vertex4RGBA>*                               pVertices,
3302                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
3303                                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
3304                                                                                   const RenderType                                                              renderType,
3305                                                                                   const ImageBackingMode                                                backingMode,
3306                                                                                   const bool                                                                    useFragmentShadingRate,
3307                                                                                   const float                                                                   depthClearValue)
3308         : m_context                                     (context)
3309         , m_pipelineConstructionType(pipelineConstructionType)
3310         , m_bindSemaphore                       (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3311         , m_colorFormat                         (colorFormat)
3312         , m_depthStencilFormat          (depthStencilFormat)
3313         , m_renderSize                          (renderSize)
3314         , m_useDepth                            (useDepth)
3315         , m_useStencil                          (useStencil)
3316         , m_useConservative                     (false)
3317         , m_multisampleStateParams      (multisampleStateParams)
3318         , m_colorBlendState                     (blendState)
3319         , m_rasterizationConservativeStateCreateInfo ()
3320         , m_renderType                          (renderType)
3321         , m_backingMode                         (backingMode)
3322         , m_depthClearValue                     (depthClearValue)
3323         , m_useFragmentShadingRate      (useFragmentShadingRate)
3324 {
3325         initialize(context, numTopologies, pTopology, pVertices);
3326 }
3327
3328 MultisampleRenderer::MultisampleRenderer (Context&                                                                              context,
3329                                                                                   const PipelineConstructionType                                pipelineConstructionType,
3330                                                                                   const VkFormat                                                                colorFormat,
3331                                                                                   const VkFormat                                                                depthStencilFormat,
3332                                                                                   const tcu::IVec2&                                                             renderSize,
3333                                                                                   const bool                                                                    useDepth,
3334                                                                                   const bool                                                                    useStencil,
3335                                                                                   const bool                                                                    useConservative,
3336                                                                                   const bool                                                                    useFragmentShadingRate,
3337                                                                                   const deUint32                                                                numTopologies,
3338                                                                                   const VkPrimitiveTopology*                                    pTopology,
3339                                                                                   const std::vector<Vertex4RGBA>*                               pVertices,
3340                                                                                   const VkPipelineMultisampleStateCreateInfo&   multisampleStateParams,
3341                                                                                   const VkPipelineColorBlendAttachmentState&    blendState,
3342                                                                                   const VkPipelineRasterizationConservativeStateCreateInfoEXT&  conservativeStateCreateInfo,
3343                                                                                   const RenderType                                                              renderType,
3344                                                                                   const ImageBackingMode                                                backingMode,
3345                                                                                   const float                                                                   depthClearValue)
3346         : m_context                                     (context)
3347         , m_pipelineConstructionType(pipelineConstructionType)
3348         , m_bindSemaphore                       (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3349         , m_colorFormat                         (colorFormat)
3350         , m_depthStencilFormat          (depthStencilFormat)
3351         , m_renderSize                          (renderSize)
3352         , m_useDepth                            (useDepth)
3353         , m_useStencil                          (useStencil)
3354         , m_useConservative                     (useConservative)
3355         , m_multisampleStateParams      (multisampleStateParams)
3356         , m_colorBlendState                     (blendState)
3357         , m_rasterizationConservativeStateCreateInfo (conservativeStateCreateInfo)
3358         , m_renderType                          (renderType)
3359         , m_backingMode                         (backingMode)
3360         , m_depthClearValue                     (depthClearValue)
3361         , m_useFragmentShadingRate      (useFragmentShadingRate)
3362 {
3363         initialize(context, numTopologies, pTopology, pVertices);
3364 }
3365
3366 void MultisampleRenderer::initialize (Context&                                                                  context,
3367                                                                           const deUint32                                                        numTopologies,
3368                                                                           const VkPrimitiveTopology*                            pTopology,
3369                                                                           const std::vector<Vertex4RGBA>*                       pVertices)
3370 {
3371         if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
3372                 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
3373
3374         const DeviceInterface&                  vk                                              = context.getDeviceInterface();
3375         const VkDevice                                  vkDevice                                = context.getDevice();
3376         const VkPhysicalDeviceFeatures  features                                = context.getDeviceFeatures();
3377         const deUint32                                  queueFamilyIndices[]    = { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
3378         const bool                                              sparse                                  = m_backingMode == IMAGE_BACKING_MODE_SPARSE;
3379         const VkComponentMapping                componentMappingRGBA    = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
3380         const VkImageCreateFlags                imageCreateFlags                = sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
3381         const VkSharingMode                             sharingMode                             = (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
3382         Allocator&                                              memAlloc                                = m_context.getDefaultAllocator();
3383         const bool                                              usesResolveImage                = m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;
3384
3385         if (sparse)
3386         {
3387                 bool sparseSamplesSupported = false;
3388                 switch(m_multisampleStateParams.rasterizationSamples)
3389                 {
3390                         case VK_SAMPLE_COUNT_1_BIT:
3391                                 sparseSamplesSupported = features.sparseResidencyImage2D;
3392                                 break;
3393                         case VK_SAMPLE_COUNT_2_BIT:
3394                                 sparseSamplesSupported = features.sparseResidency2Samples;
3395                                 break;
3396                         case VK_SAMPLE_COUNT_4_BIT:
3397                                 sparseSamplesSupported = features.sparseResidency4Samples;
3398                                 break;
3399                         case VK_SAMPLE_COUNT_8_BIT:
3400                                 sparseSamplesSupported = features.sparseResidency8Samples;
3401                                 break;
3402                         case VK_SAMPLE_COUNT_16_BIT:
3403                                 sparseSamplesSupported = features.sparseResidency16Samples;
3404                                 break;
3405                         default:
3406                                 break;
3407                 }
3408
3409                 if (!sparseSamplesSupported)
3410                         throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
3411         }
3412
3413         if (sparse && !context.getDeviceFeatures().sparseBinding)
3414                 throw tcu::NotSupportedError("No sparseBinding support");
3415
3416         // Create color image
3417         {
3418                 const VkImageUsageFlags imageUsageFlags         = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3419                         (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
3420
3421                 const VkImageCreateInfo colorImageParams        =
3422                 {
3423                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                            // VkStructureType                      sType;
3424                         DE_NULL,                                                                                                                                        // const void*                          pNext;
3425                         imageCreateFlags,                                                                                                                       // VkImageCreateFlags           flags;
3426                         VK_IMAGE_TYPE_2D,                                                                                                                       // VkImageType                          imageType;
3427                         m_colorFormat,                                                                                                                          // VkFormat                                     format;
3428                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                         // VkExtent3D                           extent;
3429                         1u,                                                                                                                                                     // deUint32                                     mipLevels;
3430                         1u,                                                                                                                                                     // deUint32                                     arrayLayers;
3431                         m_multisampleStateParams.rasterizationSamples,                                                          // VkSampleCountFlagBits        samples;
3432                         VK_IMAGE_TILING_OPTIMAL,                                                                                                        // VkImageTiling                        tiling;
3433                         imageUsageFlags,                                                                                                                        // VkImageUsageFlags            usage;
3434                         sharingMode,                                                                                                                            // VkSharingMode                        sharingMode;
3435                         sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,                                            // deUint32                                     queueFamilyIndexCount;
3436                         queueFamilyIndices,                                                                                                                     // const deUint32*                      pQueueFamilyIndices;
3437                         VK_IMAGE_LAYOUT_UNDEFINED,                                                                                                      // VkImageLayout                        initialLayout;
3438                 };
3439
3440 #ifndef CTS_USES_VULKANSC
3441                 if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
3442                         TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
3443 #endif // CTS_USES_VULKANSC
3444
3445                 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
3446
3447                 // Allocate and bind color image memory
3448                 if (sparse)
3449                 {
3450 #ifndef CTS_USES_VULKANSC
3451                         allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
3452 #endif // CTS_USES_VULKANSC
3453                 }
3454                 else
3455                 {
3456                         m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
3457                         VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
3458                 }
3459         }
3460
3461         // Create resolve image
3462         if (usesResolveImage)
3463         {
3464                 const VkImageCreateInfo resolveImageParams =
3465                 {
3466                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                    // VkStructureType                      sType;
3467                         DE_NULL,                                                                                                                                                // const void*                          pNext;
3468                         0u,                                                                                                                                                             // VkImageCreateFlags           flags;
3469                         VK_IMAGE_TYPE_2D,                                                                                                                               // VkImageType                          imageType;
3470                         m_colorFormat,                                                                                                                                  // VkFormat                                     format;
3471                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                                 // VkExtent3D                           extent;
3472                         1u,                                                                                                                                                             // deUint32                                     mipLevels;
3473                         1u,                                                                                                                                                             // deUint32                                     arrayLayers;
3474                         VK_SAMPLE_COUNT_1_BIT,                                                                                                                  // VkSampleCountFlagBits        samples;
3475                         VK_IMAGE_TILING_OPTIMAL,                                                                                                                // VkImageTiling                        tiling;
3476                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |                 // VkImageUsageFlags            usage;
3477                                 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3478                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                              // VkSharingMode                        sharingMode;
3479                         1u,                                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
3480                         queueFamilyIndices,                                                                                                                             // const deUint32*                      pQueueFamilyIndices;
3481                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                               // VkImageLayout                        initialLayout;
3482                 };
3483
3484                 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
3485
3486                 // Allocate and bind resolve image memory
3487                 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
3488                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
3489
3490                 // Create resolve attachment view
3491                 {
3492                         const VkImageViewCreateInfo resolveAttachmentViewParams =
3493                         {
3494                                 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
3495                                 DE_NULL,                                                                                // const void*                          pNext;
3496                                 0u,                                                                                             // VkImageViewCreateFlags       flags;
3497                                 *m_resolveImage,                                                                // VkImage                                      image;
3498                                 VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
3499                                 m_colorFormat,                                                                  // VkFormat                                     format;
3500                                 componentMappingRGBA,                                                   // VkComponentMapping           components;
3501                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
3502                         };
3503
3504                         m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
3505                 }
3506         }
3507
3508         // Create per-sample output images
3509         if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3510         {
3511                 const VkImageCreateInfo perSampleImageParams =
3512                 {
3513                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                    // VkStructureType                      sType;
3514                         DE_NULL,                                                                                                                                                // const void*                          pNext;
3515                         0u,                                                                                                                                                             // VkImageCreateFlags           flags;
3516                         VK_IMAGE_TYPE_2D,                                                                                                                               // VkImageType                          imageType;
3517                         m_colorFormat,                                                                                                                                  // VkFormat                                     format;
3518                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                                 // VkExtent3D                           extent;
3519                         1u,                                                                                                                                                             // deUint32                                     mipLevels;
3520                         1u,                                                                                                                                                             // deUint32                                     arrayLayers;
3521                         VK_SAMPLE_COUNT_1_BIT,                                                                                                                  // VkSampleCountFlagBits        samples;
3522                         VK_IMAGE_TILING_OPTIMAL,                                                                                                                // VkImageTiling                        tiling;
3523                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |                 // VkImageUsageFlags            usage;
3524                         VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3525                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                              // VkSharingMode                        sharingMode;
3526                         1u,                                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
3527                         queueFamilyIndices,                                                                                                                             // const deUint32*                      pQueueFamilyIndices;
3528                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                               // VkImageLayout                        initialLayout;
3529                 };
3530
3531                 m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
3532
3533                 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3534                 {
3535                         m_perSampleImages[i]    = de::SharedPtr<PerSampleImage>(new PerSampleImage);
3536                         PerSampleImage& image   = *m_perSampleImages[i];
3537
3538                         image.m_image                   = createImage(vk, vkDevice, &perSampleImageParams);
3539
3540                         // Allocate and bind image memory
3541                         image.m_imageAlloc              = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
3542                         VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
3543
3544                         // Create per-sample attachment view
3545                         {
3546                                 const VkImageViewCreateInfo perSampleAttachmentViewParams =
3547                                 {
3548                                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
3549                                         DE_NULL,                                                                                // const void*                          pNext;
3550                                         0u,                                                                                             // VkImageViewCreateFlags       flags;
3551                                         *image.m_image,                                                                 // VkImage                                      image;
3552                                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
3553                                         m_colorFormat,                                                                  // VkFormat                                     format;
3554                                         componentMappingRGBA,                                                   // VkComponentMapping           components;
3555                                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
3556                                 };
3557
3558                                 image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
3559                         }
3560                 }
3561         }
3562
3563         // Create a depth/stencil image
3564         if (m_useDepth || m_useStencil)
3565         {
3566                 const VkImageCreateInfo depthStencilImageParams =
3567                 {
3568                         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,                                                                                    // VkStructureType                      sType;
3569                         DE_NULL,                                                                                                                                                // const void*                          pNext;
3570                         0u,                                                                                                                                                             // VkImageCreateFlags           flags;
3571                         VK_IMAGE_TYPE_2D,                                                                                                                               // VkImageType                          imageType;
3572                         m_depthStencilFormat,                                                                                                                   // VkFormat                                     format;
3573                         { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u },                                 // VkExtent3D                           extent;
3574                         1u,                                                                                                                                                             // deUint32                                     mipLevels;
3575                         1u,                                                                                                                                                             // deUint32                                     arrayLayers;
3576                         m_multisampleStateParams.rasterizationSamples,                                                                  // VkSampleCountFlagBits        samples;
3577                         VK_IMAGE_TILING_OPTIMAL,                                                                                                                // VkImageTiling                        tiling;
3578                         VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,                                                                    // VkImageUsageFlags            usage;
3579                         VK_SHARING_MODE_EXCLUSIVE,                                                                                                              // VkSharingMode                        sharingMode;
3580                         1u,                                                                                                                                                             // deUint32                                     queueFamilyIndexCount;
3581                         queueFamilyIndices,                                                                                                                             // const deUint32*                      pQueueFamilyIndices;
3582                         VK_IMAGE_LAYOUT_UNDEFINED                                                                                                               // VkImageLayout                        initialLayout;
3583                 };
3584
3585                 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
3586
3587                 // Allocate and bind depth/stencil image memory
3588                 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
3589                 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
3590         }
3591
3592         // Create color attachment view
3593         {
3594                 const VkImageViewCreateInfo colorAttachmentViewParams =
3595                 {
3596                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,               // VkStructureType                      sType;
3597                         DE_NULL,                                                                                // const void*                          pNext;
3598                         0u,                                                                                             // VkImageViewCreateFlags       flags;
3599                         *m_colorImage,                                                                  // VkImage                                      image;
3600                         VK_IMAGE_VIEW_TYPE_2D,                                                  // VkImageViewType                      viewType;
3601                         m_colorFormat,                                                                  // VkFormat                                     format;
3602                         componentMappingRGBA,                                                   // VkComponentMapping           components;
3603                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }   // VkImageSubresourceRange      subresourceRange;
3604                 };
3605
3606                 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
3607         }
3608
3609         VkImageAspectFlags      depthStencilAttachmentAspect    = (VkImageAspectFlagBits)0;
3610
3611         // Create depth/stencil attachment view
3612         if (m_useDepth || m_useStencil)
3613         {
3614                 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
3615
3616                 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
3617                 {
3618                         VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,                       // VkStructureType                      sType;
3619                         DE_NULL,                                                                                        // const void*                          pNext;
3620                         0u,                                                                                                     // VkImageViewCreateFlags       flags;
3621                         *m_depthStencilImage,                                                           // VkImage                                      image;
3622                         VK_IMAGE_VIEW_TYPE_2D,                                                          // VkImageViewType                      viewType;
3623                         m_depthStencilFormat,                                                           // VkFormat                                     format;
3624                         componentMappingRGBA,                                                           // VkComponentMapping           components;
3625                         { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }        // VkImageSubresourceRange      subresourceRange;
3626                 };
3627
3628                 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
3629         }
3630
3631         // Create render pass
3632         {
3633                 std::vector<VkAttachmentDescription> attachmentDescriptions;
3634                 {
3635                         const VkAttachmentDescription colorAttachmentDescription =
3636                         {
3637                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
3638                                 m_colorFormat,                                                                          // VkFormat                                                     format;
3639                                 m_multisampleStateParams.rasterizationSamples,          // VkSampleCountFlagBits                        samples;
3640                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
3641                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
3642                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
3643                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
3644                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
3645                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
3646                         };
3647                         attachmentDescriptions.push_back(colorAttachmentDescription);
3648                 }
3649
3650                 deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
3651
3652                 if (usesResolveImage)
3653                 {
3654                         resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3655
3656                         const VkAttachmentDescription resolveAttachmentDescription =
3657                         {
3658                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
3659                                 m_colorFormat,                                                                          // VkFormat                                                     format;
3660                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
3661                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
3662                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
3663                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
3664                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
3665                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
3666                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
3667                         };
3668                         attachmentDescriptions.push_back(resolveAttachmentDescription);
3669                 }
3670
3671                 deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
3672
3673                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3674                 {
3675                         perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3676
3677                         const VkAttachmentDescription perSampleAttachmentDescription =
3678                         {
3679                                 0u,                                                                                                     // VkAttachmentDescriptionFlags         flags;
3680                                 m_colorFormat,                                                                          // VkFormat                                                     format;
3681                                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
3682                                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
3683                                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
3684                                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
3685                                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
3686                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
3687                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
3688                         };
3689
3690                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3691                         {
3692                                 attachmentDescriptions.push_back(perSampleAttachmentDescription);
3693                         }
3694                 }
3695
3696                 deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
3697
3698                 if (m_useDepth || m_useStencil)
3699                 {
3700                         depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3701
3702                         const VkAttachmentDescription depthStencilAttachmentDescription =
3703                         {
3704                                 0u,                                                                                                                                                                     // VkAttachmentDescriptionFlags         flags;
3705                                 m_depthStencilFormat,                                                                                                                           // VkFormat                                                     format;
3706                                 m_multisampleStateParams.rasterizationSamples,                                                                          // VkSampleCountFlagBits                        samples;
3707                                 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),           // VkAttachmentLoadOp                           loadOp;
3708                                 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),         // VkAttachmentStoreOp                          storeOp;
3709                                 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE),         // VkAttachmentStoreOp                          stencilLoadOp;
3710                                 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE),       // VkAttachmentStoreOp                          stencilStoreOp;
3711                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,                                                                       // VkImageLayout                                        initialLayout;
3712                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL                                                                        // VkImageLayout                                        finalLayout;
3713                         };
3714                         attachmentDescriptions.push_back(depthStencilAttachmentDescription);
3715                 }
3716
3717                 const VkAttachmentReference colorAttachmentReference =
3718                 {
3719                         0u,                                                                                                     // deUint32                     attachment;
3720                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
3721                 };
3722
3723                 const VkAttachmentReference inputAttachmentReference =
3724                 {
3725                         0u,                                                                                                     // deUint32                     attachment;
3726                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL                        // VkImageLayout        layout;
3727                 };
3728
3729                 const VkAttachmentReference resolveAttachmentReference =
3730                 {
3731                         resolveAttachmentIndex,                                                         // deUint32                     attachment;
3732                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
3733                 };
3734
3735                 const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
3736                 {
3737                         {
3738                                 VK_ATTACHMENT_UNUSED,           // deUint32                     attachment
3739                                 VK_IMAGE_LAYOUT_UNDEFINED       // VkImageLayout        layout
3740                         },
3741                         {
3742                                 0u,                                                                                     // deUint32                     attachment
3743                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
3744                         }
3745                 };
3746
3747                 const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
3748                 {
3749                         {
3750                                 VK_ATTACHMENT_UNUSED,           // deUint32                     attachment
3751                                 VK_IMAGE_LAYOUT_UNDEFINED       // VkImageLayout        layout
3752                         },
3753                         {
3754                                 resolveAttachmentIndex,                                         // deUint32                     attachment
3755                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL        // VkImageLayout        layout
3756                         }
3757                 };
3758
3759                 std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
3760                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3761                 {
3762                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3763                         {
3764                                 const VkAttachmentReference perSampleAttachmentReference =
3765                                 {
3766                                         perSampleAttachmentIndex + static_cast<deUint32>(i),    // deUint32                     attachment;
3767                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                                // VkImageLayout        layout;
3768                                 };
3769                                 perSampleAttachmentReferences[i] = perSampleAttachmentReference;
3770                         }
3771                 }
3772
3773                 const VkAttachmentReference depthStencilAttachmentReference =
3774                 {
3775                         depthStencilAttachmentIndex,                                            // deUint32                     attachment;
3776                         VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL        // VkImageLayout        layout;
3777                 };
3778
3779                 std::vector<VkSubpassDescription>       subpassDescriptions;
3780                 std::vector<VkSubpassDependency>        subpassDependencies;
3781
3782                 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3783                 {
3784                                 const VkSubpassDescription      subpassDescription0     =
3785                                 {
3786                                         0u,                                                                             // VkSubpassDescriptionFlags    flags
3787                                         VK_PIPELINE_BIND_POINT_GRAPHICS,                // VkPipelineBindPoint                  pipelineBindPoint
3788                                         0u,                                                                             // deUint32                                             inputAttachmentCount
3789                                         DE_NULL,                                                                // const VkAttachmentReference* pInputAttachments
3790                                         0u,                                                                             // deUint32                                             colorAttachmentCount
3791                                         DE_NULL,                                                                // const VkAttachmentReference* pColorAttachments
3792                                         DE_NULL,                                                                // const VkAttachmentReference* pResolveAttachments
3793                                         &depthStencilAttachmentReference,               // const VkAttachmentReference* pDepthStencilAttachment
3794                                         0u,                                                                             // deUint32                                             preserveAttachmentCount
3795                                         DE_NULL                                                                 // const VkAttachmentReference* pPreserveAttachments
3796                                 };
3797
3798                                 const VkSubpassDescription      subpassDescription1     =
3799                                 {
3800                                         0u,                                                                     // VkSubpassDescriptionFlags    flags
3801                                         VK_PIPELINE_BIND_POINT_GRAPHICS,        // VkPipelineBindPoint                  pipelineBindPoint
3802                                         0u,                                                                     // deUint32                                             inputAttachmentCount
3803                                         DE_NULL,                                                        // const VkAttachmentReference* pInputAttachments
3804                                         1u,                                                                     // deUint32                                             colorAttachmentCount
3805                                         &colorAttachmentReference,                      // const VkAttachmentReference* pColorAttachments
3806                                         &resolveAttachmentReference,            // const VkAttachmentReference* pResolveAttachments
3807                                         &depthStencilAttachmentReference,       // const VkAttachmentReference* pDepthStencilAttachment
3808                                         0u,                                                                     // deUint32                                             preserveAttachmentCount
3809                                         DE_NULL                                                         // const VkAttachmentReference* pPreserveAttachments
3810                                 };
3811
3812                                 const VkSubpassDependency       subpassDependency       =
3813                                 {
3814                                         0u,                                                                                             // deUint32                             srcSubpass
3815                                         1u,                                                                                             // deUint32                             dstSubpass
3816                                         VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,              // VkPipelineStageFlags srcStageMask
3817                                         VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,              // VkPipelineStageFlags dstStageMask
3818                                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,   // VkAccessFlags                srcAccessMask
3819                                         VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,    // VkAccessFlags                dstAccessMask
3820                                         0u                                                                                              // VkDependencyFlags    dependencyFlags
3821                                 };
3822
3823                                 subpassDescriptions.push_back(subpassDescription0);
3824                                 subpassDescriptions.push_back(subpassDescription1);
3825                                 subpassDependencies.push_back(subpassDependency);
3826                 }
3827                 else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
3828                 {
3829                         const VkSubpassDescription renderSubpassDescription =
3830                         {
3831                                 0u,                                                                                             // VkSubpassDescriptionFlags    flags
3832                                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                // VkPipelineBindPoint                  pipelineBindPoint
3833                                 0u,                                                                                             // deUint32                                             inputAttachmentCount
3834                                 DE_NULL,                                                                                // const VkAttachmentReference* pInputAttachments
3835                                 2u,                                                                                             // deUint32                                             colorAttachmentCount
3836                                 colorAttachmentReferencesUnusedAttachment,              // const VkAttachmentReference* pColorAttachments
3837                                 resolveAttachmentReferencesUnusedAttachment,    // const VkAttachmentReference* pResolveAttachments
3838                                 DE_NULL,                                                                                // const VkAttachmentReference* pDepthStencilAttachment
3839                                 0u,                                                                                             // deUint32                                             preserveAttachmentCount
3840                                 DE_NULL                                                                                 // const VkAttachmentReference* pPreserveAttachments
3841                         };
3842
3843                         subpassDescriptions.push_back(renderSubpassDescription);
3844                 }
3845                 else
3846                 {
3847                         {
3848                                 const VkSubpassDescription renderSubpassDescription =
3849                                 {
3850                                         0u,                                                                                                                                                             // VkSubpassDescriptionFlags    flags;
3851                                         VK_PIPELINE_BIND_POINT_GRAPHICS,                                                                                                // VkPipelineBindPoint                  pipelineBindPoint;
3852                                         0u,                                                                                                                                                             // deUint32                                             inputAttachmentCount;
3853                                         DE_NULL,                                                                                                                                                // const VkAttachmentReference* pInputAttachments;
3854                                         1u,                                                                                                                                                             // deUint32                                             colorAttachmentCount;
3855                                         &colorAttachmentReference,                                                                                                              // const VkAttachmentReference* pColorAttachments;
3856                                         usesResolveImage ? &resolveAttachmentReference : DE_NULL,                                               // const VkAttachmentReference* pResolveAttachments;
3857                                         (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL),              // const VkAttachmentReference* pDepthStencilAttachment;
3858                                         0u,                                                                                                                                                             // deUint32                                             preserveAttachmentCount;
3859                                         DE_NULL                                                                                                                                                 // const VkAttachmentReference* pPreserveAttachments;
3860                                 };
3861                                 subpassDescriptions.push_back(renderSubpassDescription);
3862                         }
3863
3864                         if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3865                         {
3866
3867                                 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3868                                 {
3869                                         const VkSubpassDescription copySampleSubpassDescription =
3870                                         {
3871                                                 0u,                                                                                                     // VkSubpassDescriptionFlags            flags;
3872                                                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
3873                                                 1u,                                                                                                     // deUint32                                                     inputAttachmentCount;
3874                                                 &inputAttachmentReference,                                                      // const VkAttachmentReference*         pInputAttachments;
3875                                                 1u,                                                                                                     // deUint32                                                     colorAttachmentCount;
3876                                                 &perSampleAttachmentReferences[i],                                      // const VkAttachmentReference*         pColorAttachments;
3877                                                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
3878                                                 DE_NULL,                                                                                        // const VkAttachmentReference*         pDepthStencilAttachment;
3879                                                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
3880                                                 DE_NULL                                                                                         // const VkAttachmentReference*         pPreserveAttachments;
3881                                         };
3882                                         subpassDescriptions.push_back(copySampleSubpassDescription);
3883
3884                                         const VkSubpassDependency copySampleSubpassDependency =
3885                                         {
3886                                                 0u,                                                                                                     // deUint32                                                     srcSubpass
3887                                                 1u + static_cast<deUint32>(i),                                          // deUint32                                                     dstSubpass
3888                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,          // VkPipelineStageFlags                         srcStageMask
3889                                                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                          // VkPipelineStageFlags                         dstStageMask
3890                                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                                        srcAccessMask
3891                                                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                            // VkAccessFlags                                        dstAccessMask
3892                                                 0u,                                                                                                     // VkDependencyFlags                            dependencyFlags
3893                                         };
3894                                         subpassDependencies.push_back(copySampleSubpassDependency);
3895                                 }
3896                                 // the very last sample pass must synchronize with all prior subpasses
3897                                 for (size_t i = 0; i < (m_perSampleImages.size() - 1); ++i)
3898                                 {
3899                                         const VkSubpassDependency storeSubpassDependency =
3900                                         {
3901                                                 1u + static_cast<deUint32>(i),                                          // deUint32                                                     srcSubpass
3902                                                 static_cast<deUint32>(m_perSampleImages.size()),    // deUint32                                                 dstSubpass
3903                                                 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,          // VkPipelineStageFlags                         srcStageMask
3904                                                 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,                          // VkPipelineStageFlags                         dstStageMask
3905                                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                           // VkAccessFlags                                        srcAccessMask
3906                                                 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,                            // VkAccessFlags                                        dstAccessMask
3907                                                 0u,                                                                                                     // VkDependencyFlags                            dependencyFlags
3908                                         };
3909                                         subpassDependencies.push_back(storeSubpassDependency);
3910                                 }
3911                         }
3912                 }
3913
3914                 const VkRenderPassCreateInfo renderPassParams =
3915                 {
3916                         VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                                      // VkStructureType                                      sType;
3917                         DE_NULL,                                                                                                        // const void*                                          pNext;
3918                         0u,                                                                                                                     // VkRenderPassCreateFlags                      flags;
3919                         (deUint32)attachmentDescriptions.size(),                                        // deUint32                                                     attachmentCount;
3920                         &attachmentDescriptions[0],                                                                     // const VkAttachmentDescription*       pAttachments;
3921                         (deUint32)subpassDescriptions.size(),                                           // deUint32                                                     subpassCount;
3922                         &subpassDescriptions[0],                                                                        // const VkSubpassDescription*          pSubpasses;
3923                         (deUint32)subpassDependencies.size(),                                           // deUint32                                                     dependencyCount;
3924                         subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
3925                 };
3926
3927                 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
3928         }
3929
3930         // Create framebuffer
3931         {
3932                 std::vector<VkImageView> attachments;
3933                 attachments.push_back(*m_colorAttachmentView);
3934                 if (usesResolveImage)
3935                 {
3936                         attachments.push_back(*m_resolveAttachmentView);
3937                 }
3938                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3939                 {
3940                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3941                         {
3942                                 attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
3943                         }
3944                 }
3945
3946                 if (m_useDepth || m_useStencil)
3947                 {
3948                         attachments.push_back(*m_depthStencilAttachmentView);
3949                 }
3950
3951                 const VkFramebufferCreateInfo framebufferParams =
3952                 {
3953                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,                      // VkStructureType                                      sType;
3954                         DE_NULL,                                                                                        // const void*                                          pNext;
3955                         0u,                                                                                                     // VkFramebufferCreateFlags                     flags;
3956                         *m_renderPass,                                                                          // VkRenderPass                                         renderPass;
3957                         (deUint32)attachments.size(),                                           // deUint32                                                     attachmentCount;
3958                         &attachments[0],                                                                        // const VkImageView*                           pAttachments;
3959                         (deUint32)m_renderSize.x(),                                                     // deUint32                                                     width;
3960                         (deUint32)m_renderSize.y(),                                                     // deUint32                                                     height;
3961                         1u                                                                                                      // deUint32                                                     layers;
3962                 };
3963
3964                 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
3965         }
3966
3967         // Create pipeline layout
3968         {
3969                 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
3970                 {
3971                         VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
3972                         DE_NULL,                                                                                        // const void*                                          pNext;
3973                         0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
3974                         0u,                                                                                                     // deUint32                                                     setLayoutCount;
3975                         DE_NULL,                                                                                        // const VkDescriptorSetLayout*         pSetLayouts;
3976                         0u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
3977                         DE_NULL                                                                                         // const VkPushConstantRange*           pPushConstantRanges;
3978                 };
3979
3980                 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3981
3982                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3983                 {
3984
3985                         // Create descriptor set layout
3986                         const VkDescriptorSetLayoutBinding              layoutBinding                                   =
3987                         {
3988                                 0u,                                                                                                                     // deUint32                                                             binding;
3989                                 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                                            // VkDescriptorType                                             descriptorType;
3990                                 1u,                                                                                                                     // deUint32                                                             descriptorCount;
3991                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlags                                   stageFlags;
3992                                 DE_NULL,                                                                                                        // const VkSampler*                                             pImmutableSamplers;
3993                         };
3994
3995                         const VkDescriptorSetLayoutCreateInfo   descriptorSetLayoutParams               =
3996                         {
3997                                 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,            // VkStructureType                                              sType
3998                                 DE_NULL,                                                                                                        // const void*                                                  pNext
3999                                 0u,                                                                                                                     // VkDescriptorSetLayoutCreateFlags             flags
4000                                 1u,                                                                                                                     // deUint32                                                             bindingCount
4001                                 &layoutBinding                                                                                          // const VkDescriptorSetLayoutBinding*  pBindings
4002                         };
4003                         m_copySampleDesciptorLayout     = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
4004
4005                         // Create pipeline layout
4006
4007                         const VkPushConstantRange                               pushConstantRange                               =
4008                         {
4009                                 VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlags                                   stageFlags;
4010                                 0u,                                                                                                                     // deUint32                                                             offset;
4011                                 sizeof(deInt32)                                                                                         // deUint32                                                             size;
4012                         };
4013                         const VkPipelineLayoutCreateInfo                copySamplePipelineLayoutParams  =
4014                         {
4015                                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,                          // VkStructureType                                              sType;
4016                                 DE_NULL,                                                                                                        // const void*                                                  pNext;
4017                                 0u,                                                                                                                     // VkPipelineLayoutCreateFlags                  flags;
4018                                 1u,                                                                                                                     // deUint32                                                             setLayoutCount;
4019                                 &m_copySampleDesciptorLayout.get(),                                                     // const VkDescriptorSetLayout*                 pSetLayouts;
4020                                 1u,                                                                                                                     // deUint32                                                             pushConstantRangeCount;
4021                                 &pushConstantRange                                                                                      // const VkPushConstantRange*                   pPushConstantRanges;
4022                         };
4023                         m_copySamplePipelineLayout              = createPipelineLayout(vk, vkDevice, &copySamplePipelineLayoutParams);
4024                 }
4025         }
4026
4027         m_vertexShaderModule    = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
4028         m_fragmentShaderModule  = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
4029
4030         if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4031         {
4032                 m_copySampleVertexShaderModule          = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
4033                 m_copySampleFragmentShaderModule        = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
4034         }
4035
4036         // Create pipeline
4037         {
4038                 const VkVertexInputBindingDescription   vertexInputBindingDescription =
4039                 {
4040                         0u,                                                                     // deUint32                             binding;
4041                         sizeof(Vertex4RGBA),                            // deUint32                             stride;
4042                         VK_VERTEX_INPUT_RATE_VERTEX                     // VkVertexInputRate    inputRate;
4043                 };
4044
4045                 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
4046                 {
4047                         {
4048                                 0u,                                                                     // deUint32     location;
4049                                 0u,                                                                     // deUint32     binding;
4050                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
4051                                 0u                                                                      // deUint32     offset;
4052                         },
4053                         {
4054                                 1u,                                                                     // deUint32     location;
4055                                 0u,                                                                     // deUint32     binding;
4056                                 VK_FORMAT_R32G32B32A32_SFLOAT,          // VkFormat     format;
4057                                 DE_OFFSET_OF(Vertex4RGBA, color),       // deUint32     offset;
4058                         }
4059                 };
4060
4061                 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
4062                 {
4063                         VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
4064                         DE_NULL,                                                                                                                // const void*                                                          pNext;
4065                         0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
4066                         1u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
4067                         &vertexInputBindingDescription,                                                                 // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
4068                         2u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
4069                         vertexInputAttributeDescriptions                                                                // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
4070                 };
4071
4072                 const std::vector<VkViewport>   viewports               { makeViewport(m_renderSize) };
4073                 const std::vector<VkRect2D>             scissors                { makeRect2D(m_renderSize) };
4074
4075                 const deUint32                                  attachmentCount = m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;
4076
4077                 std::vector<VkPipelineColorBlendAttachmentState> attachments;
4078
4079                 for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
4080                         attachments.push_back(m_colorBlendState);
4081
4082                 VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
4083                 {
4084                         VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
4085                         DE_NULL,                                                                                                        // const void*                                                                  pNext;
4086                         0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
4087                         false,                                                                                                          // VkBool32                                                                             logicOpEnable;
4088                         VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
4089                         attachmentCount,                                                                                        // deUint32                                                                             attachmentCount;
4090                         attachments.data(),                                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
4091                         { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
4092                 };
4093
4094                 const VkStencilOpState stencilOpState =
4095                 {
4096                         VK_STENCIL_OP_KEEP,                                             // VkStencilOp  failOp;
4097                         VK_STENCIL_OP_REPLACE,                                  // VkStencilOp  passOp;
4098                         VK_STENCIL_OP_KEEP,                                             // VkStencilOp  depthFailOp;
4099                         VK_COMPARE_OP_GREATER,                                  // VkCompareOp  compareOp;
4100                         1u,                                                                             // deUint32             compareMask;
4101                         1u,                                                                             // deUint32             writeMask;
4102                         1u,                                                                             // deUint32             reference;
4103                 };
4104
4105                 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
4106                 {
4107                         VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,     // VkStructureType                                                      sType;
4108                         DE_NULL,                                                                                                        // const void*                                                          pNext;
4109                         0u,                                                                                                                     // VkPipelineDepthStencilStateCreateFlags       flags;
4110                         m_useDepth,                                                                                                     // VkBool32                                                                     depthTestEnable;
4111                         m_useDepth,                                                                                                     // VkBool32                                                                     depthWriteEnable;
4112                         VK_COMPARE_OP_LESS,                                                                                     // VkCompareOp                                                          depthCompareOp;
4113                         false,                                                                                                          // VkBool32                                                                     depthBoundsTestEnable;
4114                         m_useStencil,                                                                                           // VkBool32                                                                     stencilTestEnable;
4115                         stencilOpState,                                                                                         // VkStencilOpState                                                     front;
4116                         stencilOpState,                                                                                         // VkStencilOpState                                                     back;
4117                         0.0f,                                                                                                           // float                                                                        minDepthBounds;
4118                         1.0f,                                                                                                           // float                                                                        maxDepthBounds;
4119                 };
4120
4121                 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo
4122                 {
4123                         VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,                                             // VkStructureType                                                              sType
4124                         m_useConservative ? &m_rasterizationConservativeStateCreateInfo : DE_NULL,              // const void*                                                                  pNext
4125                         0u,                                                                                                                                                             // VkPipelineRasterizationStateCreateFlags              flags
4126                         VK_FALSE,                                                                                                                                               // VkBool32                                                                             depthClampEnable
4127                         VK_FALSE,                                                                                                                                               // VkBool32                                                                             rasterizerDiscardEnable
4128                         VK_POLYGON_MODE_FILL,                                                                                                                   // VkPolygonMode                                                                polygonMode
4129                         VK_CULL_MODE_NONE,                                                                                                                              // VkCullModeFlags                                                              cullMode
4130                         VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                                                // VkFrontFace                                                                  frontFace
4131                         VK_FALSE,                                                                                                                                               // VkBool32                                                                             depthBiasEnable
4132                         0.0f,                                                                                                                                                   // float                                                                                depthBiasConstantFactor
4133                         0.0f,                                                                                                                                                   // float                                                                                depthBiasClamp
4134                         0.0f,                                                                                                                                                   // float                                                                                depthBiasSlopeFactor
4135                         1.0f                                                                                                                                                    // float                                                                                lineWidth
4136                 };
4137
4138                 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo
4139                 {
4140                         VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR,                                                         // VkStructureType                                              sType;
4141                         DE_NULL,                                                                                                                                                                                        // const void*                                                  pNext;
4142                         { 2, 2 },                                                                                                                                                                                       // VkExtent2D                                                   fragmentSize;
4143                         { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR },       // VkFragmentShadingRateCombinerOpKHR   combinerOps[2];
4144                 };
4145
4146                 const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;
4147
4148                 m_graphicsPipelines.reserve(numSubpasses * numTopologies);
4149                 for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
4150                 {
4151                         if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4152                         {
4153                                 if (subpassIdx == 0)
4154                                 {
4155                                         colorBlendStateParams.attachmentCount = 0;
4156                                 }
4157                                 else
4158                                 {
4159                                         colorBlendStateParams.attachmentCount = 1;
4160                                 }
4161                         }
4162                         for (deUint32 i = 0u; i < numTopologies; ++i)
4163                         {
4164                                 m_graphicsPipelines.emplace_back(vk, vkDevice, m_pipelineConstructionType);
4165                                 m_graphicsPipelines.back().setDefaultTopology(pTopology[i])
4166                                                                                   .setupVertexInputState(&vertexInputStateParams)
4167                                                                                   .setupPreRasterizationShaderState(viewports,
4168                                                                                                                                                         scissors,
4169                                                                                                                                                         *m_pipelineLayout,
4170                                                                                                                                                         *m_renderPass,
4171                                                                                                                                                         subpassIdx,
4172                                                                                                                                                         *m_vertexShaderModule,
4173                                                                                                                                                         &rasterizationStateCreateInfo,
4174                                                                                                                                                         DE_NULL, DE_NULL, DE_NULL, DE_NULL,
4175                                                                                                                                                         (m_useFragmentShadingRate ? &shadingRateStateCreateInfo : nullptr))
4176                                                                                   .setupFragmentShaderState(*m_pipelineLayout,
4177                                                                                                                                         *m_renderPass,
4178                                                                                                                                         subpassIdx,
4179                                                                                                                                         *m_fragmentShaderModule,
4180                                                                                                                                         &depthStencilStateParams,
4181                                                                                                                                         &m_multisampleStateParams)
4182                                                                                   .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &m_multisampleStateParams)
4183                                                                                   .setMonolithicPipelineLayout(*m_pipelineLayout)
4184                                                                                   .buildPipeline();
4185                         }
4186                         }
4187         }
4188
4189         if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4190         {
4191                 // Create pipelines for copying samples to single sampled images
4192                 {
4193                         const VkPipelineVertexInputStateCreateInfo vertexInputStateParams
4194                         {
4195                                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                                                      sType;
4196                                 DE_NULL,                                                                                                                // const void*                                                          pNext;
4197                                 0u,                                                                                                                             // VkPipelineVertexInputStateCreateFlags        flags;
4198                                 0u,                                                                                                                             // deUint32                                                                     vertexBindingDescriptionCount;
4199                                 DE_NULL,                                                                                                                // const VkVertexInputBindingDescription*       pVertexBindingDescriptions;
4200                                 0u,                                                                                                                             // deUint32                                                                     vertexAttributeDescriptionCount;
4201                                 DE_NULL                                                                                                                 // const VkVertexInputAttributeDescription*     pVertexAttributeDescriptions;
4202                         };
4203
4204                         const std::vector<VkViewport>   viewports       { makeViewport(m_renderSize) };
4205                         const std::vector<VkRect2D>             scissors        { makeRect2D(m_renderSize) };
4206
4207                         const VkPipelineColorBlendStateCreateInfo colorBlendStateParams
4208                         {
4209                                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,       // VkStructureType                                                              sType;
4210                                 DE_NULL,                                                                                                        // const void*                                                                  pNext;
4211                                 0u,                                                                                                                     // VkPipelineColorBlendStateCreateFlags                 flags;
4212                                 false,                                                                                                          // VkBool32                                                                             logicOpEnable;
4213                                 VK_LOGIC_OP_COPY,                                                                                       // VkLogicOp                                                                    logicOp;
4214                                 1u,                                                                                                                     // deUint32                                                                             attachmentCount;
4215                                 &m_colorBlendState,                                                                                     // const VkPipelineColorBlendAttachmentState*   pAttachments;
4216                                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                      // float                                                                                blendConstants[4];
4217                         };
4218
4219                         m_copySamplePipelines.reserve(m_perSampleImages.size());
4220                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4221                         {
4222                                 // Pipeline is to be used in subpasses subsequent to sample-shading subpass
4223
4224                                 const deUint32 subpassIdx = 1u + (deUint32)i;
4225                                 m_copySamplePipelines.emplace_back(vk, vkDevice, m_pipelineConstructionType);
4226                                 m_copySamplePipelines.back().setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
4227                                                                                         .setDefaultRasterizationState()
4228                                                                                         .setDefaultMultisampleState()
4229                                                                                         .setDefaultDepthStencilState()
4230                                                                                         .setupVertexInputState(&vertexInputStateParams)
4231                                                                                         .setupPreRasterizationShaderState(viewports,
4232                                                                                                                                                         scissors,
4233                                                                                                                                                         *m_copySamplePipelineLayout,
4234                                                                                                                                                         *m_renderPass,
4235                                                                                                                                                         subpassIdx,
4236                                                                                                                                                         *m_copySampleVertexShaderModule)
4237                                                                                         .setupFragmentShaderState(*m_copySamplePipelineLayout,
4238                                                                                                                                         *m_renderPass,
4239                                                                                                                                         subpassIdx,
4240                                                                                                                                         *m_copySampleFragmentShaderModule)
4241                                                                                         .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams)
4242                                                                                         .setMonolithicPipelineLayout(*m_copySamplePipelineLayout)
4243                                                                                         .buildPipeline();
4244                         }
4245                 }
4246
4247                 const VkDescriptorPoolSize                      descriptorPoolSize
4248                 {
4249                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                                    // VkDescriptorType                                     type;
4250                         1u                                                                                                              // deUint32                                                     descriptorCount;
4251                 };
4252
4253                 const VkDescriptorPoolCreateInfo        descriptorPoolCreateInfo
4254                 {
4255                         VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,                  // VkStructureType                                      sType
4256                         DE_NULL,                                                                                                // const void*                                          pNext
4257                         VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,              // VkDescriptorPoolCreateFlags          flags
4258                         1u,                                                                                                     // deUint32                                                     maxSets
4259                         1u,                                                                                                             // deUint32                                                     poolSizeCount
4260                         &descriptorPoolSize                                                                             // const VkDescriptorPoolSize*          pPoolSizes
4261                 };
4262
4263                 m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
4264
4265                 const VkDescriptorSetAllocateInfo       descriptorSetAllocateInfo
4266                 {
4267                         VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,                 // VkStructureType                                      sType
4268                         DE_NULL,                                                                                                // const void*                                          pNext
4269                         *m_copySampleDesciptorPool,                                                             // VkDescriptorPool                                     descriptorPool
4270                         1u,                                                                                                             // deUint32                                                     descriptorSetCount
4271                         &m_copySampleDesciptorLayout.get(),                                             // const VkDescriptorSetLayout*         pSetLayouts
4272                 };
4273
4274                 m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
4275
4276                 const VkDescriptorImageInfo                     imageInfo
4277                 {
4278                         DE_NULL,
4279                         *m_colorAttachmentView,
4280                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
4281                 };
4282                 const VkWriteDescriptorSet                      descriptorWrite
4283                 {
4284                         VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,                 // VkStructureType                                      sType;
4285                         DE_NULL,                                                                                // const void*                                          pNext;
4286                         *m_copySampleDesciptorSet,                                              // VkDescriptorSet                                      dstSet;
4287                         0u,                                                                                             // deUint32                                                     dstBinding;
4288                         0u,                                                                                             // deUint32                                                     dstArrayElement;
4289                         1u,                                                                                             // deUint32                                                     descriptorCount;
4290                         VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT,                    // VkDescriptorType                                     descriptorType;
4291                         &imageInfo,                                                                             // const VkDescriptorImageInfo*         pImageInfo;
4292                         DE_NULL,                                                                                // const VkDescriptorBufferInfo*        pBufferInfo;
4293                         DE_NULL,                                                                                // const VkBufferView*                          pTexelBufferView;
4294                 };
4295                 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
4296         }
4297
4298         // Create vertex buffer
4299         {
4300                 const VkBufferCreateInfo vertexBufferParams
4301                 {
4302                         VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,           // VkStructureType              sType;
4303                         DE_NULL,                                                                        // const void*                  pNext;
4304                         0u,                                                                                     // VkBufferCreateFlags  flags;
4305                         1024u,                                                                          // VkDeviceSize                 size;
4306                         VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,                      // VkBufferUsageFlags   usage;
4307                         VK_SHARING_MODE_EXCLUSIVE,                                      // VkSharingMode                sharingMode;
4308                         1u,                                                                                     // deUint32                             queueFamilyIndexCount;
4309                         &queueFamilyIndices[0]                                          // const deUint32*              pQueueFamilyIndices;
4310                 };
4311
4312                 m_vertexBuffer          = createBuffer(vk, vkDevice, &vertexBufferParams);
4313                 m_vertexBufferAlloc     = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
4314
4315                 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
4316
4317                 // Load vertices into vertex buffer
4318                 {
4319                         Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
4320
4321                         if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4322                         {
4323                                 DE_ASSERT(numTopologies == 1);
4324
4325                                 std::vector<Vertex4RGBA> vertices = pVertices[0];
4326
4327                                 // Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
4328                                 for (size_t i = 0; i < vertices.size(); i++)
4329                                         vertices[i].color.w() = 0.0f;
4330
4331                                 deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));
4332
4333                                 pDst += vertices.size();
4334
4335                                 // The second draw uses original vertices which are pure red.
4336                                 deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
4337                         }
4338                         else
4339                         {
4340                                 for (deUint32 i = 0u; i < numTopologies; ++i)
4341                                 {
4342                                         deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
4343                                         pDst += pVertices[i].size();
4344                                 }
4345                         }
4346                 }
4347                 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
4348         }
4349
4350         // Create command pool
4351         m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
4352
4353         // Create command buffer
4354         {
4355                 VkClearValue colorClearValue;
4356                 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4357                 {
4358                         colorClearValue.color.float32[0] = 0.25;
4359                         colorClearValue.color.float32[1] = 0.25;
4360                         colorClearValue.color.float32[2] = 0.25;
4361                         colorClearValue.color.float32[3] = 1.0f;
4362                 }
4363                 else
4364                 {
4365                         colorClearValue.color.float32[0] = 0.0f;
4366                         colorClearValue.color.float32[1] = 0.0f;
4367                         colorClearValue.color.float32[2] = 0.0f;
4368                         colorClearValue.color.float32[3] = 0.0f;
4369                 }
4370
4371                 VkClearValue depthStencilClearValue;
4372                 depthStencilClearValue.depthStencil.depth = m_depthClearValue;
4373                 depthStencilClearValue.depthStencil.stencil = 0u;
4374
4375                 std::vector<VkClearValue> clearValues;
4376                 clearValues.push_back(colorClearValue);
4377                 if (usesResolveImage)
4378                 {
4379                         clearValues.push_back(colorClearValue);
4380                 }
4381                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4382                 {
4383                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4384                         {
4385                                 clearValues.push_back(colorClearValue);
4386                         }
4387                 }
4388                 if (m_useDepth || m_useStencil)
4389                 {
4390                         clearValues.push_back(depthStencilClearValue);
4391                 }
4392
4393                 vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
4394                 std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
4395
4396                 {
4397                         const VkImageMemoryBarrier colorImageBarrier =
4398                         // color attachment image
4399                         {
4400                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4401                                 DE_NULL,                                                                                // const void*                          pNext;
4402                                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
4403                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
4404                                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
4405                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        newLayout;
4406                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4407                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4408                                 *m_colorImage,                                                                  // VkImage                                      image;
4409                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
4410                         };
4411                         imageLayoutBarriers.push_back(colorImageBarrier);
4412                 }
4413                 if (usesResolveImage)
4414                 {
4415                         const VkImageMemoryBarrier resolveImageBarrier =
4416                         // resolve attachment image
4417                         {
4418                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4419                                 DE_NULL,                                                                                // const void*                          pNext;
4420                                 0u,                                                                                             // VkAccessFlags                        srcAccessMask;
4421                                 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
4422                                 VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
4423                                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        newLayout;
4424                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4425                                 VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4426                                 *m_resolveImage,                                                                // VkImage                                      image;
4427                                 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
4428                         };
4429                         imageLayoutBarriers.push_back(resolveImageBarrier);
4430                 }
4431                 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4432                 {
4433                         for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4434                         {
4435                                 const VkImageMemoryBarrier perSampleImageBarrier =
4436                                 // resolve attachment image
4437                                 {
4438                                         VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                 // VkStructureType                      sType;
4439                                         DE_NULL,                                                                                // const void*                          pNext;
4440                                         0u,                                                                                             // VkAccessFlags                        srcAccessMask;
4441                                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,                   // VkAccessFlags                        dstAccessMask;
4442                                         VK_IMAGE_LAYOUT_UNDEFINED,                                              // VkImageLayout                        oldLayout;
4443                                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,               // VkImageLayout                        newLayout;
4444                                         VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     srcQueueFamilyIndex;
4445                                         VK_QUEUE_FAMILY_IGNORED,                                                // deUint32                                     dstQueueFamilyIndex;
4446                                         *m_perSampleImages[i]->m_image,                                 // VkImage                                      image;
4447                                         { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u },  // VkImageSubresourceRange      subresourceRange;
4448                                 };
4449                                 imageLayoutBarriers.push_back(perSampleImageBarrier);
4450                         }
4451                 }
4452                 if (m_useDepth || m_useStencil)
4453                 {
4454                         const VkImageMemoryBarrier depthStencilImageBarrier =
4455                         // depth/stencil attachment image
4456                         {
4457                                 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,                         // VkStructureType                      sType;
4458                                 DE_NULL,                                                                                        // const void*                          pNext;
4459                                 0u,                                                                                                     // VkAccessFlags                        srcAccessMask;
4460                                 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,           // VkAccessFlags                        dstAccessMask;
4461                                 VK_IMAGE_LAYOUT_UNDEFINED,                                                      // VkImageLayout                        oldLayout;
4462                                 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,       // VkImageLayout                        newLayout;
4463                                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     srcQueueFamilyIndex;
4464                                 VK_QUEUE_FAMILY_IGNORED,                                                        // deUint32                                     dstQueueFamilyIndex;
4465                                 *m_depthStencilImage,                                                           // VkImage                                      image;
4466                                 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u },       // VkImageSubresourceRange      subresourceRange;
4467                         };
4468                         imageLayoutBarriers.push_back(depthStencilImageBarrier);
4469                         dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
4470                 }
4471
4472                 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4473
4474                 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
4475
4476                 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
4477                         0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
4478
4479                 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
4480
4481                 VkDeviceSize vertexBufferOffset = 0u;
4482
4483                 for (deUint32 i = 0u; i < numTopologies; ++i)
4484                 {
4485                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipelines[i].getPipeline());
4486                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4487                         vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
4488
4489                         vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
4490                 }
4491
4492                 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4493                 {
4494                         // The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
4495                         vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
4496                         vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipelines[1].getPipeline());
4497                         vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4498                         // The depth test should pass as the first draw didn't touch the depth buffer.
4499                         vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
4500                 }
4501                 else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4502                 {
4503                         // Copy each sample id to single sampled image
4504                         for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
4505                         {
4506                                 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
4507                                 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_copySamplePipelines[sampleId].getPipeline());
4508                                 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
4509                                 vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
4510                                 vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
4511                         }
4512                 }
4513
4514                 endRenderPass(vk, *m_cmdBuffer);
4515
4516                 endCommandBuffer(vk, *m_cmdBuffer);
4517         }
4518 }
4519
4520 MultisampleRenderer::~MultisampleRenderer (void)
4521 {
4522 }
4523
4524 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
4525 {
4526         const DeviceInterface&          vk                                      = m_context.getDeviceInterface();
4527         const VkDevice                          vkDevice                        = m_context.getDevice();
4528         const VkQueue                           queue                           = m_context.getUniversalQueue();
4529         const deUint32                          queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
4530
4531         submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
4532
4533         if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
4534         {
4535                 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
4536         }
4537         else if(m_renderType == RENDER_TYPE_SINGLE_SAMPLE)
4538         {
4539                 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_colorImage, m_colorFormat, m_renderSize.cast<deUint32>());
4540         }
4541         else
4542         {
4543                 return de::MovePtr<tcu::TextureLevel>();
4544         }
4545 }
4546
4547 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
4548 {
4549         return readColorAttachment(m_context.getDeviceInterface(), m_context.getDevice(), m_context.getUniversalQueue(), m_context.getUniversalQueueFamilyIndex(), m_context.getDefaultAllocator(), *m_perSampleImages[sampleId]->m_image, m_colorFormat, m_renderSize.cast<deUint32>());
4550 }
4551
4552 // Multisample tests with subpasses using no attachments.
4553 class VariableRateTestCase : public vkt::TestCase
4554 {
4555 public:
4556         using SampleCounts = std::vector<vk::VkSampleCountFlagBits>;
4557
4558         struct PushConstants
4559         {
4560                 int width;
4561                 int height;
4562                 int samples;
4563         };
4564
4565         struct TestParams
4566         {
4567                 PipelineConstructionType        pipelineConstructionType;       // The way pipeline is constructed.
4568                 bool                                            nonEmptyFramebuffer;            // Empty framebuffer or not.
4569                 vk::VkSampleCountFlagBits       fbCount;                                        // If not empty, framebuffer sample count.
4570                 bool                                            unusedAttachment;                       // If not empty, create unused attachment or not.
4571                 SampleCounts                            subpassCounts;                          // Counts for the different subpasses.
4572                 bool                                            useFragmentShadingRate;         // Use pipeline fragment shading rate.
4573         };
4574
4575         static const deInt32 kWidth             = 256u;
4576         static const deInt32 kHeight    = 256u;
4577
4578                                                                         VariableRateTestCase    (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
4579         virtual                                                 ~VariableRateTestCase   (void) {}
4580
4581         virtual void                                    initPrograms                    (vk::SourceCollections& programCollection) const;
4582         virtual TestInstance*                   createInstance                  (Context& context) const;
4583         virtual void                                    checkSupport                    (Context& context) const;
4584
4585         static constexpr vk::VkFormat   kColorFormat                    = vk::VK_FORMAT_R8G8B8A8_UNORM;
4586
4587 private:
4588         TestParams m_params;
4589 };
4590
4591 class VariableRateTestInstance : public vkt::TestInstance
4592 {
4593 public:
4594         using TestParams = VariableRateTestCase::TestParams;
4595
4596                                                                 VariableRateTestInstance        (Context& context, const TestParams& counts);
4597         virtual                                         ~VariableRateTestInstance       (void) {}
4598
4599         virtual tcu::TestStatus         iterate                                         (void);
4600
4601 private:
4602         TestParams m_params;
4603 };
4604
4605 VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
4606         : vkt::TestCase (testCtx, name, description)
4607         , m_params              (params)
4608 {
4609 }
4610
4611 void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const
4612 {
4613         std::stringstream vertSrc;
4614
4615         vertSrc << "#version 450\n"
4616                         << "\n"
4617                         << "layout(location=0) in vec2 inPos;\n"
4618                         << "\n"
4619                         << "void main() {\n"
4620                         << "    gl_Position = vec4(inPos, 0.0, 1.0);\n"
4621                         << "}\n"
4622                         ;
4623
4624         std::stringstream fragSrc;
4625
4626         fragSrc << "#version 450\n"
4627                         << "\n"
4628                         << "layout(set=0, binding=0, std430) buffer OutBuffer {\n"
4629                         << "    int coverage[];\n"
4630                         << "} out_buffer;\n"
4631                         << "\n"
4632                         << "layout(push_constant) uniform PushConstants {\n"
4633                         << "    int width;\n"
4634                         << "    int height;\n"
4635                         << "    int samples;\n"
4636                         << "} push_constants;\n"
4637                         << "\n"
4638                         << "void main() {\n"
4639                         << "   ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n"
4640                         << "   int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n"
4641                         << "   out_buffer.coverage[pos] = 1;\n"
4642                         << "}\n"
4643                         ;
4644
4645         programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str());
4646         programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str());
4647 }
4648
4649 TestInstance* VariableRateTestCase::createInstance (Context& context) const
4650 {
4651         return new VariableRateTestInstance(context, m_params);
4652 }
4653
4654 void VariableRateTestCase::checkSupport (Context& context) const
4655 {
4656         const auto&     vki                             = context.getInstanceInterface();
4657         const auto      physicalDevice  = context.getPhysicalDevice();
4658
4659         // When using multiple subpasses, require variableMultisampleRate.
4660         if (m_params.subpassCounts.size() > 1)
4661         {
4662                 if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate)
4663                         TCU_THROW(NotSupportedError, "Variable multisample rate not supported");
4664         }
4665
4666         // Check if sampleRateShading is supported.
4667         if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading)
4668                 TCU_THROW(NotSupportedError, "Sample rate shading is not supported");
4669
4670         // Make sure all subpass sample counts are supported.
4671         const auto      properties              = vk::getPhysicalDeviceProperties(vki, physicalDevice);
4672         const auto&     supportedCounts = properties.limits.framebufferNoAttachmentsSampleCounts;
4673
4674         for (const auto count : m_params.subpassCounts)
4675         {
4676                 if ((supportedCounts & count) == 0u)
4677                         TCU_THROW(NotSupportedError, "Sample count combination not supported");
4678         }
4679
4680         if (m_params.nonEmptyFramebuffer)
4681         {
4682                 // Check the framebuffer sample count is supported.
4683                 const auto formatProperties = vk::getPhysicalDeviceImageFormatProperties(vki, physicalDevice, kColorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, 0u);
4684                 if ((formatProperties.sampleCounts & m_params.fbCount) == 0u)
4685                         TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment");
4686         }
4687
4688         if (m_params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_params.fbCount))
4689                 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
4690
4691         checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
4692 }
4693
4694 void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size)
4695 {
4696         auto& alloc = buffer.getAllocation();
4697         deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size));
4698         vk::flushAlloc(vkd, device, alloc);
4699 }
4700
4701 VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params)
4702         : vkt::TestInstance     (context)
4703         , m_params                      (params)
4704 {
4705 }
4706
4707 tcu::TestStatus VariableRateTestInstance::iterate (void)
4708 {
4709         using PushConstants = VariableRateTestCase::PushConstants;
4710
4711         const auto&     vkd                     = m_context.getDeviceInterface();
4712         const auto      device          = m_context.getDevice();
4713         auto&           allocator       = m_context.getDefaultAllocator();
4714         const auto&     queue           = m_context.getUniversalQueue();
4715         const auto      queueIndex      = m_context.getUniversalQueueFamilyIndex();
4716
4717         const vk::VkDeviceSize  kWidth                  = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth);
4718         const vk::VkDeviceSize  kHeight                 = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight);
4719         constexpr auto                  kColorFormat    = VariableRateTestCase::kColorFormat;
4720
4721         const auto kWidth32             = static_cast<deUint32>(kWidth);
4722         const auto kHeight32    = static_cast<deUint32>(kHeight);
4723
4724         std::vector<std::unique_ptr<vk::BufferWithMemory>>      referenceBuffers;
4725         std::vector<std::unique_ptr<vk::BufferWithMemory>>      outputBuffers;
4726         std::vector<size_t>                                                                     bufferNumElements;
4727         std::vector<vk::VkDeviceSize>                                           bufferSizes;
4728
4729         // Create reference and output buffers.
4730         for (const auto count : m_params.subpassCounts)
4731         {
4732                 bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count));
4733                 bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32));
4734                 const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
4735
4736                 referenceBuffers.emplace_back   (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
4737                 outputBuffers.emplace_back              (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
4738         }
4739
4740         // Descriptor set layout.
4741         vk::DescriptorSetLayoutBuilder builder;
4742         builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
4743         const auto descriptorSetLayout = builder.build(vkd, device);
4744
4745         // Pipeline layout.
4746         const vk::VkPushConstantRange pushConstantRange =
4747         {
4748                 vk::VK_SHADER_STAGE_FRAGMENT_BIT,                               //      VkShaderStageFlags      stageFlags;
4749                 0u,                                                                                             //      deUint32                        offset;
4750                 static_cast<deUint32>(sizeof(PushConstants)),   //      deUint32                        size;
4751         };
4752
4753         const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
4754         {
4755                 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,      //      VkStructureType                                 sType;
4756                 nullptr,                                                                                        //      const void*                                             pNext;
4757                 0u,                                                                                                     //      VkPipelineLayoutCreateFlags             flags;
4758                 1u,                                                                                                     //      deUint32                                                setLayoutCount;
4759                 &descriptorSetLayout.get(),                                                     //      const VkDescriptorSetLayout*    pSetLayouts;
4760                 1u,                                                                                                     //      deUint32                                                pushConstantRangeCount;
4761                 &pushConstantRange,                                                                     //      const VkPushConstantRange*              pPushConstantRanges;
4762         };
4763         const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
4764
4765         // Subpass with no attachments.
4766         const vk::VkSubpassDescription emptySubpassDescription =
4767         {
4768                 0u,                                                                             //      VkSubpassDescriptionFlags               flags;
4769                 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,    //      VkPipelineBindPoint                             pipelineBindPoint;
4770                 0u,                                                                             //      deUint32                                                inputAttachmentCount;
4771                 nullptr,                                                                //      const VkAttachmentReference*    pInputAttachments;
4772                 0u,                                                                             //      deUint32                                                colorAttachmentCount;
4773                 nullptr,                                                                //      const VkAttachmentReference*    pColorAttachments;
4774                 nullptr,                                                                //      const VkAttachmentReference*    pResolveAttachments;
4775                 nullptr,                                                                //      const VkAttachmentReference*    pDepthStencilAttachment;
4776                 0u,                                                                             //      deUint32                                                preserveAttachmentCount;
4777                 nullptr,                                                                //      const deUint32*                                 pPreserveAttachments;
4778         };
4779
4780         // Unused attachment reference.
4781         const vk::VkAttachmentReference unusedAttachmentReference =
4782         {
4783                 VK_ATTACHMENT_UNUSED,                                                   //      deUint32                attachment;
4784                 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,   //      VkImageLayout   layout;
4785         };
4786
4787         // Subpass with unused attachment.
4788         const vk::VkSubpassDescription unusedAttachmentSubpassDescription =
4789         {
4790                 0u,                                                                             //      VkSubpassDescriptionFlags               flags;
4791                 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,    //      VkPipelineBindPoint                             pipelineBindPoint;
4792                 0u,                                                                             //      deUint32                                                inputAttachmentCount;
4793                 nullptr,                                                                //      const VkAttachmentReference*    pInputAttachments;
4794                 1u,                                                                             //      deUint32                                                colorAttachmentCount;
4795                 &unusedAttachmentReference,                             //      const VkAttachmentReference*    pColorAttachments;
4796                 nullptr,                                                                //      const VkAttachmentReference*    pResolveAttachments;
4797                 nullptr,                                                                //      const VkAttachmentReference*    pDepthStencilAttachment;
4798                 0u,                                                                             //      deUint32                                                preserveAttachmentCount;
4799                 nullptr,                                                                //      const deUint32*                                 pPreserveAttachments;
4800         };
4801
4802         // Renderpass with multiple subpasses.
4803         vk::VkRenderPassCreateInfo renderPassCreateInfo =
4804         {
4805                 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,  //      VkStructureType                                 sType;
4806                 nullptr,                                                                                //      const void*                                             pNext;
4807                 0u,                                                                                             //      VkRenderPassCreateFlags                 flags;
4808                 0u,                                                                                             //      deUint32                                                attachmentCount;
4809                 nullptr,                                                                                //      const VkAttachmentDescription*  pAttachments;
4810                 0u,                                                                                             //      deUint32                                                subpassCount;
4811                 nullptr,                                                                                //      const VkSubpassDescription*             pSubpasses;
4812                 0u,                                                                                             //      deUint32                                                dependencyCount;
4813                 nullptr,                                                                                //      const VkSubpassDependency*              pDependencies;
4814         };
4815
4816         std::vector<vk::VkSubpassDescription> subpassesVector;
4817
4818         for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
4819                 subpassesVector.push_back(emptySubpassDescription);
4820         renderPassCreateInfo.subpassCount       = static_cast<deUint32>(subpassesVector.size());
4821         renderPassCreateInfo.pSubpasses         = subpassesVector.data();
4822         const auto renderPassMultiplePasses = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
4823
4824         // Render pass with single subpass.
4825         const vk::VkAttachmentDescription colorAttachmentDescription =
4826         {
4827                 0u,                                                                                             //      VkAttachmentDescriptionFlags    flags;
4828                 kColorFormat,                                                                   //      VkFormat                                                format;
4829                 m_params.fbCount,                                                               //      VkSampleCountFlagBits                   samples;
4830                 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    //      VkAttachmentLoadOp                              loadOp;
4831                 vk::VK_ATTACHMENT_STORE_OP_STORE,                               //      VkAttachmentStoreOp                             storeOp;
4832                 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE,                    //      VkAttachmentLoadOp                              stencilLoadOp;
4833                 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE,                   //      VkAttachmentStoreOp                             stencilStoreOp;
4834                 vk::VK_IMAGE_LAYOUT_UNDEFINED,                                  //      VkImageLayout                                   initialLayout;
4835                 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,   //      VkImageLayout                                   finalLayout;
4836         };
4837
4838         if (m_params.nonEmptyFramebuffer)
4839         {
4840                 renderPassCreateInfo.attachmentCount = 1u;
4841                 renderPassCreateInfo.pAttachments = &colorAttachmentDescription;
4842         }
4843         const bool unusedAttachmentSubpass      = (m_params.nonEmptyFramebuffer && m_params.unusedAttachment);
4844         renderPassCreateInfo.subpassCount       = 1u;
4845         renderPassCreateInfo.pSubpasses         = (unusedAttachmentSubpass ? &unusedAttachmentSubpassDescription : &emptySubpassDescription);
4846         const auto renderPassSingleSubpass      = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
4847
4848         // Framebuffers.
4849         vk::VkFramebufferCreateInfo framebufferCreateInfo =
4850         {
4851                 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,  //      VkStructureType                         sType;
4852                 nullptr,                                                                                //      const void*                                     pNext;
4853                 0u,                                                                                             //      VkFramebufferCreateFlags        flags;
4854                 DE_NULL,                                                                                //      VkRenderPass                            renderPass;
4855                 0u,                                                                                             //      deUint32                                        attachmentCount;
4856                 nullptr,                                                                                //      const VkImageView*                      pAttachments;
4857                 kWidth32,                                                                               //      deUint32                                        width;
4858                 kHeight32,                                                                              //      deUint32                                        height;
4859                 1u,                                                                                             //      deUint32                                        layers;
4860         };
4861
4862         // Framebuffer for multiple-subpasses render pass.
4863         framebufferCreateInfo.renderPass                = renderPassMultiplePasses.get();
4864         const auto framebufferMultiplePasses    = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
4865
4866         // Framebuffer for single-subpass render pass.
4867         std::unique_ptr<vk::ImageWithMemory>    imagePtr;
4868         vk::Move<vk::VkImageView>                               imageView;
4869
4870         if (m_params.nonEmptyFramebuffer)
4871         {
4872                 const vk::VkImageCreateInfo imageCreateInfo =
4873                 {
4874                         vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,        //      VkStructureType                 sType;
4875                         nullptr,                                                                        //      const void*                             pNext;
4876                         0u,                                                                                     //      VkImageCreateFlags              flags;
4877                         vk::VK_IMAGE_TYPE_2D,                                           //      VkImageType                             imageType;
4878                         kColorFormat,                                                           //      VkFormat                                format;
4879                         vk::makeExtent3D(kWidth32, kHeight32, 1u),      //      VkExtent3D                              extent;
4880                         1u,                                                                                     //      deUint32                                mipLevels;
4881                         1u,                                                                                     //      deUint32                                arrayLayers;
4882                         m_params.fbCount,                                                       //      VkSampleCountFlagBits   samples;
4883                         vk::VK_IMAGE_TILING_OPTIMAL,                            //      VkImageTiling                   tiling;
4884                         vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,        //      VkImageUsageFlags               usage;
4885                         vk::VK_SHARING_MODE_EXCLUSIVE,                          //      VkSharingMode                   sharingMode;
4886                         0u,                                                                                     //      deUint32                                queueFamilyIndexCount;
4887                         nullptr,                                                                        //      const deUint32*                 pQueueFamilyIndices;
4888                         vk::VK_IMAGE_LAYOUT_UNDEFINED,                          //      VkImageLayout                   initialLayout;
4889                 };
4890                 imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any});
4891
4892                 const auto subresourceRange     = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4893                 imageView                                       = vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange);
4894
4895                 framebufferCreateInfo.attachmentCount   = 1u;
4896                 framebufferCreateInfo.pAttachments              = &imageView.get();
4897         }
4898         framebufferCreateInfo.renderPass        = renderPassSingleSubpass.get();
4899         const auto framebufferSingleSubpass     = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
4900
4901         // Shader modules and stages.
4902         const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
4903         const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
4904
4905         // Vertices, input state and assembly.
4906         const std::vector<tcu::Vec2> vertices =
4907         {
4908                 { -0.987f, -0.964f },
4909                 {  0.982f, -0.977f },
4910                 {  0.005f,  0.891f },
4911         };
4912
4913         const auto vertexBinding        = vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX);
4914         const auto vertexAttribute      = vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u);
4915
4916         const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
4917         {
4918                 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,  //      VkStructureType                                                         sType;
4919                 nullptr,                                                                                                                //      const void*                                                                     pNext;
4920                 0u,                                                                                                                             //      VkPipelineVertexInputStateCreateFlags           flags;
4921                 1u,                                                                                                                             //      deUint32                                                                        vertexBindingDescriptionCount;
4922                 &vertexBinding,                                                                                                 //      const VkVertexInputBindingDescription*          pVertexBindingDescriptions;
4923                 1u,                                                                                                                             //      deUint32                                                                        vertexAttributeDescriptionCount;
4924                 &vertexAttribute,                                                                                               //      const VkVertexInputAttributeDescription*        pVertexAttributeDescriptions;
4925         };
4926
4927         // Graphics pipelines to create output buffers.
4928         const std::vector<VkViewport>   viewport        { vk::makeViewport(kWidth32, kHeight32) };
4929         const std::vector<VkRect2D>             scissor         { vk::makeRect2D(kWidth32, kHeight32) };
4930
4931         const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
4932
4933         const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
4934         {
4935                 VK_FALSE,                               //      VkBool32                                blendEnable;
4936                 VK_BLEND_FACTOR_ZERO,   //      VkBlendFactor                   srcColorBlendFactor;
4937                 VK_BLEND_FACTOR_ZERO,   //      VkBlendFactor                   dstColorBlendFactor;
4938                 VK_BLEND_OP_ADD,                //      VkBlendOp                               colorBlendOp;
4939                 VK_BLEND_FACTOR_ZERO,   //      VkBlendFactor                   srcAlphaBlendFactor;
4940                 VK_BLEND_FACTOR_ZERO,   //      VkBlendFactor                   dstAlphaBlendFactor;
4941                 VK_BLEND_OP_ADD,                //      VkBlendOp                               alphaBlendOp;
4942                 colorComponentFlags,    //      VkColorComponentFlags   colorWriteMask;
4943         };
4944
4945         const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoNoAttachments =
4946         {
4947                 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,   // VkStructureType                                                              sType;
4948                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
4949                 0u,                                                                                                                             // VkPipelineColorBlendStateCreateFlags                 flags;
4950                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
4951                 vk::VK_LOGIC_OP_CLEAR,                                                                                  // VkLogicOp                                                                    logicOp;
4952                 0u,                                                                                                                             // deUint32                                                                             attachmentCount;
4953                 nullptr,                                                                                                                // const VkPipelineColorBlendAttachmentState*   pAttachments;
4954                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                              // float                                                                                blendConstants[4];
4955         };
4956
4957         const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoOneAttachment =
4958         {
4959                 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,   // VkStructureType                                                              sType;
4960                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
4961                 0u,                                                                                                                             // VkPipelineColorBlendStateCreateFlags                 flags;
4962                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
4963                 vk::VK_LOGIC_OP_CLEAR,                                                                                  // VkLogicOp                                                                    logicOp;
4964                 1u,                                                                                                                             // deUint32                                                                             attachmentCount;
4965                 &colorBlendAttachmentState,                                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
4966                 { 0.0f, 0.0f, 0.0f, 0.0f }                                                                              // float                                                                                blendConstants[4];
4967         };
4968
4969         vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo
4970         {
4971                 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,   //      VkStructureType                                                 sType;
4972                 nullptr,                                                                                                                //      const void*                                                             pNext;
4973                 0u,                                                                                                                             //      VkPipelineMultisampleStateCreateFlags   flags;
4974                 vk::VK_SAMPLE_COUNT_1_BIT,                                                                              //      VkSampleCountFlagBits                                   rasterizationSamples;
4975                 VK_FALSE,                                                                                                               //      VkBool32                                                                sampleShadingEnable;
4976                 0.0f,                                                                                                                   //      float                                                                   minSampleShading;
4977                 nullptr,                                                                                                                //      const VkSampleMask*                                             pSampleMask;
4978                 VK_FALSE,                                                                                                               //      VkBool32                                                                alphaToCoverageEnable;
4979                 VK_FALSE,                                                                                                               //      VkBool32                                                                alphaToOneEnable;
4980         };
4981
4982         std::vector<GraphicsPipelineWrapper> outputPipelines;
4983         outputPipelines.reserve(m_params.subpassCounts.size());
4984         for (const auto samples : m_params.subpassCounts)
4985         {
4986                 const auto colorBlendStatePtr = (unusedAttachmentSubpass ? &colorBlendStateCreateInfoOneAttachment : &colorBlendStateCreateInfoNoAttachments);
4987
4988                 multisampleStateCreateInfo.rasterizationSamples = samples;
4989
4990                 outputPipelines.emplace_back(vkd, device, m_params.pipelineConstructionType);
4991                 outputPipelines.back()
4992                         .setDefaultDepthStencilState()
4993                         .setDefaultRasterizationState()
4994                         .setupVertexInputState(&vertexInputStateCreateInfo)
4995                         .setupPreRasterizationShaderState(viewport,
4996                                 scissor,
4997                                 *pipelineLayout,
4998                                 *renderPassSingleSubpass,
4999                                 0u,
5000                                 *vertModule)
5001                         .setupFragmentShaderState(*pipelineLayout, *renderPassSingleSubpass, 0u, *fragModule, DE_NULL, &multisampleStateCreateInfo)
5002                         .setupFragmentOutputState(*renderPassSingleSubpass, 0u, colorBlendStatePtr, &multisampleStateCreateInfo)
5003                         .setMonolithicPipelineLayout(*pipelineLayout)
5004                         .buildPipeline();
5005         }
5006
5007         // Graphics pipelines with variable rate but using several subpasses.
5008         std::vector<GraphicsPipelineWrapper> referencePipelines;
5009         referencePipelines.reserve(m_params.subpassCounts.size());
5010         for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
5011         {
5012                 multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i];
5013
5014                 deUint32 subpass = static_cast<deUint32>(i);
5015                 referencePipelines.emplace_back(vkd, device, m_params.pipelineConstructionType);
5016                 referencePipelines.back()
5017                         .setDefaultDepthStencilState()
5018                         .setDefaultRasterizationState()
5019                         .setupVertexInputState(&vertexInputStateCreateInfo)
5020                         .setupPreRasterizationShaderState(viewport,
5021                                 scissor,
5022                                 *pipelineLayout,
5023                                 *renderPassMultiplePasses,
5024                                 subpass,
5025                                 *vertModule)
5026                         .setupFragmentShaderState(*pipelineLayout, *renderPassMultiplePasses, subpass, *fragModule, DE_NULL, &multisampleStateCreateInfo)
5027                         .setupFragmentOutputState(*renderPassMultiplePasses, subpass, &colorBlendStateCreateInfoNoAttachments, &multisampleStateCreateInfo)
5028                         .setMonolithicPipelineLayout(*pipelineLayout)
5029                         .buildPipeline();
5030         }
5031
5032         // Prepare vertex, reference and output buffers.
5033         const auto                              vertexBufferSize                = vertices.size() * sizeof(decltype(vertices)::value_type);
5034         const auto                              vertexBufferCreateInfo  = vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
5035         vk::BufferWithMemory    vertexBuffer                    {vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible};
5036         auto&                                   vertexAlloc                             = vertexBuffer.getAllocation();
5037
5038         deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize);
5039         vk::flushAlloc(vkd, device, vertexAlloc);
5040
5041         for (size_t i = 0; i < referenceBuffers.size(); ++i)
5042         {
5043                 zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]);
5044                 zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]);
5045         }
5046
5047         // Prepare descriptor sets.
5048         const deUint32                          totalSets               = static_cast<deUint32>(referenceBuffers.size() * 2u);
5049         vk::DescriptorPoolBuilder       poolBuilder;
5050         poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u));
5051         const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets);
5052
5053         std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets        (referenceBuffers.size());
5054         std::vector<vk::Move<vk::VkDescriptorSet>> outputSets           (outputBuffers.size());
5055
5056         for (auto& set : referenceSets)
5057                 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
5058         for (auto& set : outputSets)
5059                 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
5060
5061         vk::DescriptorSetUpdateBuilder updateBuilder;
5062
5063         for (size_t i = 0; i < referenceSets.size(); ++i)
5064         {
5065                 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]);
5066                 updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
5067         }
5068         for (size_t i = 0; i < outputSets.size(); ++i)
5069         {
5070                 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]);
5071                 updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
5072         }
5073
5074         updateBuilder.update(vkd, device);
5075
5076         // Prepare command pool.
5077         const auto cmdPool              = vk::makeCommandPool(vkd, device, queueIndex);
5078         const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5079         const auto cmdBuffer    = cmdBufferPtr.get();
5080
5081         vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier =
5082         {
5083                 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,    //      VkStructureType sType;
5084                 nullptr,                                                                                //      const void*             pNext;
5085                 vk::VK_ACCESS_SHADER_WRITE_BIT,                                 //      VkAccessFlags   srcAccessMask;
5086                 vk::VK_ACCESS_HOST_READ_BIT,                                    //      VkAccessFlags   dstAccessMask;
5087                 VK_QUEUE_FAMILY_IGNORED,                                                //      deUint32                srcQueueFamilyIndex;
5088                 VK_QUEUE_FAMILY_IGNORED,                                                //      deUint32                dstQueueFamilyIndex;
5089                 DE_NULL,                                                                                //      VkBuffer                buffer;
5090                 0u,                                                                                             //      VkDeviceSize    offset;
5091                 VK_WHOLE_SIZE,                                                                  //      VkDeviceSize    size;
5092         };
5093
5094         // Record command buffer.
5095         const vk::VkDeviceSize  vertexBufferOffset      = 0u;
5096         const auto                              renderArea                      = vk::makeRect2D(kWidth32, kHeight32);
5097         PushConstants                   pushConstants           = { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 };
5098
5099         vk::beginCommandBuffer(vkd, cmdBuffer);
5100
5101         // Render output buffers.
5102         vk::beginRenderPass(vkd, cmdBuffer, renderPassSingleSubpass.get(), framebufferSingleSubpass.get(), renderArea);
5103         for (size_t i = 0; i < outputBuffers.size(); ++i)
5104         {
5105                 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, outputPipelines[i].getPipeline());
5106                 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr);
5107                 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
5108                 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
5109                 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
5110                 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
5111         }
5112         vk::endRenderPass(vkd, cmdBuffer);
5113         for (size_t i = 0; i < outputBuffers.size(); ++i)
5114         {
5115                 storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get();
5116                 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
5117         }
5118
5119         // Render reference buffers.
5120         vk::beginRenderPass(vkd, cmdBuffer, renderPassMultiplePasses.get(), framebufferMultiplePasses.get(), renderArea);
5121         for (size_t i = 0; i < referenceBuffers.size(); ++i)
5122         {
5123                 if (i > 0)
5124                         vkd.cmdNextSubpass(cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE);
5125                 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, referencePipelines[i].getPipeline());
5126                 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr);
5127                 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
5128                 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
5129                 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
5130                 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
5131         }
5132         vk::endRenderPass(vkd, cmdBuffer);
5133         for (size_t i = 0; i < referenceBuffers.size(); ++i)
5134         {
5135                 storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get();
5136                 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
5137         }
5138
5139         vk::endCommandBuffer(vkd, cmdBuffer);
5140
5141         // Run all pipelines.
5142         vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
5143
5144         // Invalidate reference allocs.
5145 #undef LOG_BUFFER_CONTENTS
5146 #ifdef LOG_BUFFER_CONTENTS
5147         auto& log = m_context.getTestContext().getLog();
5148 #endif
5149         for (size_t i = 0; i < referenceBuffers.size(); ++i)
5150         {
5151                 auto& buffer    = referenceBuffers[i];
5152                 auto& alloc             = buffer->getAllocation();
5153                 vk::invalidateAlloc(vkd, device, alloc);
5154
5155 #ifdef LOG_BUFFER_CONTENTS
5156                 std::vector<deInt32> bufferValues(bufferNumElements[i]);
5157                 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
5158
5159                 std::ostringstream msg;
5160                 for (const auto value : bufferValues)
5161                         msg << " " << value;
5162                 log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
5163 #endif
5164         }
5165
5166         for (size_t i = 0; i < outputBuffers.size(); ++i)
5167         {
5168                 auto& buffer    = outputBuffers[i];
5169                 auto& alloc             = buffer->getAllocation();
5170                 vk::invalidateAlloc(vkd, device, alloc);
5171
5172 #ifdef LOG_BUFFER_CONTENTS
5173                 std::vector<deInt32> bufferValues(bufferNumElements[i]);
5174                 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
5175
5176                 std::ostringstream msg;
5177                 for (const auto value : bufferValues)
5178                         msg << " " << value;
5179                 log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
5180 #endif
5181
5182                 if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0)
5183                         return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i));
5184         }
5185
5186         return tcu::TestStatus::pass("Pass");
5187 }
5188
5189 using ElementsVector    = std::vector<vk::VkSampleCountFlagBits>;
5190 using CombinationVector = std::vector<ElementsVector>;
5191
5192 void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial)
5193 {
5194         if (partial.size() == requestedSize)
5195                 solutions.push_back(partial);
5196         else
5197         {
5198                 for (const auto& elem : elements)
5199                 {
5200                         partial.push_back(elem);
5201                         combinationsRecursive(elements, requestedSize, solutions, partial);
5202                         partial.pop_back();
5203                 }
5204         }
5205 }
5206
5207 CombinationVector combinations(const ElementsVector& elements, size_t requestedSize)
5208 {
5209         CombinationVector solutions;
5210         ElementsVector partial;
5211
5212         combinationsRecursive(elements, requestedSize, solutions, partial);
5213         return solutions;
5214 }
5215
5216 } // anonymous
5217
5218 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, bool useFragmentShadingRate)
5219 {
5220         const VkSampleCountFlagBits samples[] =
5221         {
5222                 VK_SAMPLE_COUNT_2_BIT,
5223                 VK_SAMPLE_COUNT_4_BIT,
5224                 VK_SAMPLE_COUNT_8_BIT,
5225                 VK_SAMPLE_COUNT_16_BIT,
5226                 VK_SAMPLE_COUNT_32_BIT,
5227                 VK_SAMPLE_COUNT_64_BIT
5228         };
5229
5230         const char*             groupName[]             { "multisample", "multisample_with_fragment_shading_rate" };
5231         de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, groupName[useFragmentShadingRate], ""));
5232
5233         // Rasterization samples tests
5234         {
5235                 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
5236
5237                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5238                 {
5239                         std::ostringstream caseName;
5240                         caseName << "samples_" << samples[samplesNdx];
5241
5242                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5243
5244                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "",  pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5245                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "",              pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5246                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5247                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "",             pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5248
5249                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "",                       pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT, useFragmentShadingRate));
5250                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "",                     pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT, useFragmentShadingRate));
5251                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil", "",       pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT, useFragmentShadingRate));
5252
5253 #ifndef CTS_USES_VULKANSC
5254                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "",   pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5255                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "",               pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5256                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "",  pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5257                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "",              pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5258
5259                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_sparse", "",                        pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT, useFragmentShadingRate));
5260                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil_sparse", "",                      pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_STENCIL_BIT, useFragmentShadingRate));
5261                         samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth_stencil_sparse", "",        pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, TEST_MODE_DEPTH_BIT | TEST_MODE_STENCIL_BIT, useFragmentShadingRate));
5262 #endif // CTS_USES_VULKANSC
5263                         rasterizationSamplesTests->addChild(samplesTests.release());
5264                 }
5265
5266                 multisampleTests->addChild(rasterizationSamplesTests.release());
5267         }
5268
5269         // Raster samples consistency check
5270 #ifndef CTS_USES_VULKANSC
5271         {
5272                 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests   (new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
5273                 MultisampleTestParams                   paramsRegular                                   = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate };
5274                 MultisampleTestParams                   paramsSparse                                    = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate };
5275
5276                 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
5277                                                                         "unique_colors_check",
5278                                                                         "",
5279                                                                         checkSupport,
5280                                                                         initMultisamplePrograms,
5281                                                                         testRasterSamplesConsistency,
5282                                                                         paramsRegular);
5283                 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
5284                                                                         "unique_colors_check_sparse",
5285                                                                         "",
5286                                                                         checkSupport,
5287                                                                         initMultisamplePrograms,
5288                                                                         testRasterSamplesConsistency,
5289                                                                         paramsSparse);
5290                 multisampleTests->addChild(rasterSamplesConsistencyTests.release());
5291
5292         }
5293 #endif // CTS_USES_VULKANSC
5294
5295         // minSampleShading tests
5296         {
5297                 struct TestConfig
5298                 {
5299                         const char*     name;
5300                         float           minSampleShading;
5301                 };
5302
5303                 const TestConfig testConfigs[] =
5304                 {
5305                         { "min_0_0",    0.0f },
5306                         { "min_0_25",   0.25f },
5307                         { "min_0_5",    0.5f },
5308                         { "min_0_75",   0.75f },
5309                         { "min_1_0",    1.0f }
5310                 };
5311
5312                 {
5313                         de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
5314
5315                         for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5316                         {
5317                                 const TestConfig&                               testConfig                              = testConfigs[configNdx];
5318                                 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests    (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5319
5320                                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5321                                 {
5322                                         std::ostringstream caseName;
5323                                         caseName << "samples_" << samples[samplesNdx];
5324
5325                                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5326
5327                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle",  "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5328                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line",              "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5329                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5330                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point",             "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5331 #ifndef CTS_USES_VULKANSC
5332                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle_sparse",   "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate));
5333                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line_sparse",               "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate));
5334                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_1px_sparse",  "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate));
5335                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point_sparse",              "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, true, useFragmentShadingRate));
5336 #endif // CTS_USES_VULKANSC
5337
5338                                         minShadingValueTests->addChild(samplesTests.release());
5339                                 }
5340
5341                                 minSampleShadingTests->addChild(minShadingValueTests.release());
5342                         }
5343
5344                         multisampleTests->addChild(minSampleShadingTests.release());
5345                 }
5346
5347                 {
5348                         de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled", ""));
5349
5350                         for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5351                         {
5352                                 const TestConfig&                               testConfig                              = testConfigs[configNdx];
5353                                 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests    (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5354
5355                                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5356                                 {
5357                                         std::ostringstream caseName;
5358                                         caseName << "samples_" << samples[samplesNdx];
5359
5360                                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5361
5362                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5363
5364                                         minShadingValueTests->addChild(samplesTests.release());
5365                                 }
5366
5367                                 minSampleShadingTests->addChild(minShadingValueTests.release());
5368                         }
5369
5370                         multisampleTests->addChild(minSampleShadingTests.release());
5371                 }
5372
5373                 {
5374                         de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled", ""));
5375
5376                         for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5377                         {
5378                                 const TestConfig&                               testConfig                              = testConfigs[configNdx];
5379                                 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests    (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5380
5381                                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5382                                 {
5383                                         std::ostringstream caseName;
5384                                         caseName << "samples_" << samples[samplesNdx];
5385
5386                                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5387
5388                                         samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false, useFragmentShadingRate));
5389
5390                                         minShadingValueTests->addChild(samplesTests.release());
5391                                 }
5392
5393                                 minSampleShadingTests->addChild(minShadingValueTests.release());
5394                         }
5395
5396                         multisampleTests->addChild(minSampleShadingTests.release());
5397                 }
5398         }
5399
5400         // SampleMask tests
5401         {
5402                 struct TestConfig
5403                 {
5404                         const char*             name;
5405                         const char*             description;
5406                         VkSampleMask    sampleMask;
5407                 };
5408
5409                 const TestConfig testConfigs[] =
5410                 {
5411                         { "mask_all_on",        "All mask bits are off",                        0x0 },
5412                         { "mask_all_off",       "All mask bits are on",                         0xFFFFFFFF },
5413                         { "mask_one",           "All mask elements are 0x1",            0x1},
5414                         { "mask_random",        "All mask elements are 0xAAAAAAAA",     0xAAAAAAAA },
5415                 };
5416
5417                 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
5418
5419                 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5420                 {
5421                         const TestConfig&                               testConfig                              = testConfigs[configNdx];
5422                         de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests    (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
5423
5424                         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5425                         {
5426                                 std::ostringstream caseName;
5427                                 caseName << "samples_" << samples[samplesNdx];
5428
5429                                 const deUint32                                  sampleMaskCount = samples[samplesNdx] / 32;
5430                                 de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5431
5432                                 std::vector<VkSampleMask> mask;
5433                                 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
5434                                         mask.push_back(testConfig.sampleMask);
5435
5436                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5437                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5438                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5439                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5440 #ifndef CTS_USES_VULKANSC
5441                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5442                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5443                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5444                                 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5445 #endif // CTS_USES_VULKANSC
5446
5447                                 sampleMaskValueTests->addChild(samplesTests.release());
5448                         }
5449
5450                         sampleMaskTests->addChild(sampleMaskValueTests.release());
5451                 }
5452
5453                 multisampleTests->addChild(sampleMaskTests.release());
5454
5455         }
5456
5457         // AlphaToOne tests
5458         {
5459                 const VkSampleCountFlagBits samplesForAlphaToOne[] =
5460                 {
5461                         VK_SAMPLE_COUNT_1_BIT,
5462                         VK_SAMPLE_COUNT_2_BIT,
5463                         VK_SAMPLE_COUNT_4_BIT,
5464                         VK_SAMPLE_COUNT_8_BIT,
5465                         VK_SAMPLE_COUNT_16_BIT,
5466                         VK_SAMPLE_COUNT_32_BIT,
5467                         VK_SAMPLE_COUNT_64_BIT
5468                 };
5469                 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
5470
5471                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samplesForAlphaToOne); samplesNdx++)
5472                 {
5473                         std::ostringstream caseName;
5474                         caseName << "samples_" << samplesForAlphaToOne[samplesNdx];
5475
5476                         alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5477 #ifndef CTS_USES_VULKANSC
5478                         caseName << "_sparse";
5479                         alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5480 #endif // CTS_USES_VULKANSC
5481                 }
5482
5483                 multisampleTests->addChild(alphaToOneTests.release());
5484         }
5485
5486         // AlphaToCoverageEnable tests
5487         {
5488                 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
5489
5490                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5491                 {
5492                         std::ostringstream caseName;
5493                         caseName << "samples_" << samples[samplesNdx];
5494
5495                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5496
5497                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5498                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5499                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5500 #ifndef CTS_USES_VULKANSC
5501                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5502                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5503                         samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5504 #endif // CTS_USES_VULKANSC
5505
5506                         alphaToCoverageTests->addChild(samplesTests.release());
5507                 }
5508                 multisampleTests->addChild(alphaToCoverageTests.release());
5509         }
5510
5511         // AlphaToCoverageEnable without color buffer tests
5512         {
5513                 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));
5514
5515                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5516                 {
5517                         std::ostringstream caseName;
5518                         caseName << "samples_" << samples[samplesNdx];
5519
5520                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5521
5522                         samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5523 #ifndef CTS_USES_VULKANSC
5524                         samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5525 #endif // CTS_USES_VULKANSC
5526
5527                         alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
5528                 }
5529                 multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
5530         }
5531
5532         // AlphaToCoverageEnable with unused color attachment:
5533         // Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
5534         {
5535                 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));
5536
5537                 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5538                 {
5539                         std::ostringstream caseName;
5540                         caseName << "samples_" << samples[samplesNdx];
5541
5542                         de::MovePtr<tcu::TestCaseGroup> samplesTests    (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5543
5544                         samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5545 #ifndef CTS_USES_VULKANSC
5546                         samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5547 #endif // CTS_USES_VULKANSC
5548                         samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5549 #ifndef CTS_USES_VULKANSC
5550                         samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5551 #endif // CTS_USES_VULKANSC
5552
5553                         alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
5554                 }
5555                 multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
5556         }
5557
5558 #ifndef CTS_USES_VULKANSC
5559         // not all tests need to be repeated for FSR
5560         if (useFragmentShadingRate == false)
5561         {
5562                 // Sampling from a multisampled image texture (texelFetch)
5563                 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx, pipelineConstructionType));
5564
5565                 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
5566                 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx, pipelineConstructionType));
5567
5568                 // Sampling from a multisampled image texture (texelFetch), checking supersample positions
5569                 multisampleTests->addChild(createMultisampleStandardSamplePositionTests(testCtx, pipelineConstructionType));
5570
5571                 // VK_AMD_shader_fragment_mask
5572                 multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx, pipelineConstructionType));
5573
5574                 // Multisample resolve tests where a render area is less than an attachment size.
5575                 multisampleTests->addChild(createMultisampleResolveRenderpassRenderAreaTests(testCtx, pipelineConstructionType));
5576
5577                 // VK_EXT_multisampled_render_to_single_sampled
5578                 {
5579                         multisampleTests->addChild(createMultisampledRenderToSingleSampledTests(testCtx, pipelineConstructionType));
5580                         // Take advantage of the code for this extension's tests to add some normal multisampling tests
5581                         multisampleTests->addChild(createMultisampledMiscTests(testCtx, pipelineConstructionType));
5582                 }
5583         }
5584
5585         // VK_EXT_sample_locations
5586         multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx, pipelineConstructionType, useFragmentShadingRate));
5587
5588         // VK_AMD_mixed_attachment
5589         multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx, pipelineConstructionType, useFragmentShadingRate));
5590
5591         // Sample mask with and without vk_ext_post_depth_coverage
5592         {
5593                 const vk::VkSampleCountFlagBits standardSamplesSet[] =
5594                 {
5595                         vk::VK_SAMPLE_COUNT_2_BIT,
5596                         vk::VK_SAMPLE_COUNT_4_BIT,
5597                         vk::VK_SAMPLE_COUNT_8_BIT,
5598                         vk::VK_SAMPLE_COUNT_16_BIT
5599                 };
5600
5601                 de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
5602
5603                 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
5604                 {
5605                         std::ostringstream caseName;
5606                         caseName << "samples_" << standardSamplesSet[ndx];
5607
5608                         sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", pipelineConstructionType, standardSamplesSet[ndx], false, useFragmentShadingRate));
5609
5610                         caseName << "_post_depth_coverage";
5611                         sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", pipelineConstructionType, standardSamplesSet[ndx], true, useFragmentShadingRate));
5612
5613                 }
5614                 multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
5615         }
5616 #endif // CTS_USES_VULKANSC
5617
5618         {
5619                 //Conservative rasterization test
5620                 struct TestConfig
5621                 {
5622                         const char*             name;
5623                         const char*             description;
5624                         bool                    enableMinSampleShading;
5625                         const float             minSampleShading;
5626                         const bool              enableSampleMask;
5627                         VkSampleMask    sampleMask;
5628                         bool                    enablePostDepthCoverage;
5629                 };
5630
5631                 const TestConfig testConfigs[] =
5632                 {
5633                         { "plain_conservative",         "Only conservative rendering applied",  false,          0.0f,           false,          0x0,                    false },
5634                         { "post_depth_coverage",        "Post depth coverage enabled",                  false,          0.0f,           false,          0x0,                    true },
5635                         { "min_0_25",                           "minSampleMask set to 0.25f",                   true,           0.25f,          false,          0x0,                    false },
5636                         { "min_0_5",                            "minSampleMask set to 0.5f",                    true,           0.5f,           false,          0x0,                    false },
5637                         { "min_0_75",                           "minSampleMask set to 0.75f",                   true,           0.75f,          false,          0x0,                    false },
5638                         { "min_0_1_0",                          "minSampleMask set to 1.0f",                    true,           1.0f,           false,          0x0,                    false },
5639                         { "mask_all_off",                       "All mask bits are on",                                 false,          0.0f,           true,           0x0,                    false },
5640                         { "mask_all_on",                        "All mask bits are off",                                false,          0.0f,           true,           0xFFFFFFFF,             false },
5641                         { "mask_half_on",                       "All mask elements are 0xAAAAAAAA",             false,          0.0f,           true,           0xAAAAAAAA,             false },
5642                 };
5643
5644                 const vk::VkSampleCountFlagBits standardSamplesSet[] =
5645                 {
5646                         vk::VK_SAMPLE_COUNT_2_BIT,
5647                         vk::VK_SAMPLE_COUNT_4_BIT,
5648                         vk::VK_SAMPLE_COUNT_8_BIT,
5649                         vk::VK_SAMPLE_COUNT_16_BIT
5650                 };
5651
5652                 enum vk::VkConservativeRasterizationModeEXT rasterizationMode[] =
5653                 {
5654                         vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,
5655                         vk::VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT
5656                 };
5657
5658                 // Conservative rendering
5659                 de::MovePtr<tcu::TestCaseGroup> conservativeGroup(new tcu::TestCaseGroup(testCtx, "conservative_with_full_coverage", ""));
5660
5661                 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(rasterizationMode); ++modeNdx)
5662                 {
5663                         const char* modeName = (modeNdx == 0 ? "overestimate" : "underestimate");
5664                         de::MovePtr<tcu::TestCaseGroup> modesGroup(new tcu::TestCaseGroup(testCtx, modeName, ""));
5665
5666                         for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++samplesNdx)
5667                         {
5668                                 std::string caseName = "samples_" + std::to_string(standardSamplesSet[samplesNdx]) + "_";
5669
5670                                 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5671                                 {
5672                                         const TestConfig&                               testConfig                              = testConfigs[configNdx];
5673
5674                                         modesGroup->addChild(new SampleMaskWithConservativeTest(testCtx, caseName + testConfig.name, testConfig.description, pipelineConstructionType, standardSamplesSet[samplesNdx],
5675                                                                                                                                                         rasterizationMode[modeNdx], testConfig.enableMinSampleShading, testConfig.minSampleShading, testConfig.enableSampleMask,
5676                                                                                                                                                         testConfig.sampleMask, testConfig.enablePostDepthCoverage, useFragmentShadingRate));
5677                                 }
5678
5679                         }
5680
5681                         conservativeGroup->addChild(modesGroup.release());
5682                 }
5683
5684                 multisampleTests->addChild(conservativeGroup.release());
5685         }
5686
5687         {
5688                 static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts =
5689                 {
5690                         vk::VK_SAMPLE_COUNT_1_BIT,
5691                         vk::VK_SAMPLE_COUNT_2_BIT,
5692                         vk::VK_SAMPLE_COUNT_4_BIT,
5693                         vk::VK_SAMPLE_COUNT_8_BIT,
5694                         vk::VK_SAMPLE_COUNT_16_BIT,
5695                         vk::VK_SAMPLE_COUNT_32_BIT,
5696                         vk::VK_SAMPLE_COUNT_64_BIT,
5697                 };
5698
5699
5700                 static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }};
5701
5702                 {
5703                         de::MovePtr<tcu::TestCaseGroup> variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate", "Tests for multisample variable rate in subpasses"));
5704
5705                         // 2 and 3 subpasses should be good enough.
5706                         static const std::vector<size_t> combinationSizes = { 2, 3 };
5707
5708                         // Basic cases.
5709                         for (const auto size : combinationSizes)
5710                         {
5711                                 const auto combs = combinations(kSampleCounts, size);
5712                                 for (const auto& comb : combs)
5713                                 {
5714                                         // Check sample counts actually vary between some of the subpasses.
5715                                         std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
5716                                         if (uniqueVals.size() < 2)
5717                                                 continue;
5718
5719                                         std::ostringstream name;
5720                                         std::ostringstream desc;
5721
5722                                         bool first = true;
5723                                         for (const auto& count : comb)
5724                                         {
5725                                                 name << (first ? "" : "_") << count;
5726                                                 desc << (first ? "Subpasses with counts " : ", ") << count;
5727                                                 first = false;
5728                                         }
5729
5730                                         const VariableRateTestCase::TestParams params =
5731                                         {
5732                                                 pipelineConstructionType,       //      PipelineConstructionType        pipelineConstructionType;
5733                                                 false,                                          //      bool                                            nonEmptyFramebuffer;
5734                                                 vk::VK_SAMPLE_COUNT_1_BIT,      //      vk::VkSampleCountFlagBits       fbCount;
5735                                                 false,                                          //      bool                                            unusedAttachment;
5736                                                 comb,                                           //      SampleCounts                            subpassCounts;
5737                                                 useFragmentShadingRate,         //      bool                                            useFragmentShadingRate;
5738                                         };
5739                                         variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
5740                                 }
5741                         }
5742
5743                         // Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations.
5744                         {
5745                                 // Use one more sample count for the framebuffer attachment. It will be taken from the last item.
5746                                 auto combs = combinations(kSampleCounts, 2 + 1);
5747                                 for (auto& comb : combs)
5748                                 {
5749                                         // Framebuffer sample count.
5750                                         const auto fbCount = comb.back();
5751                                         comb.pop_back();
5752
5753                                         // Check sample counts actually vary between some of the subpasses.
5754                                         std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
5755                                         if (uniqueVals.size() < 2)
5756                                                 continue;
5757
5758                                         for (const auto flag : unusedAttachmentFlag)
5759                                         {
5760                                                 std::ostringstream name;
5761                                                 std::ostringstream desc;
5762
5763                                                 desc << "Framebuffer with sample count " << fbCount << " and subpasses with counts ";
5764
5765                                                 bool first = true;
5766                                                 for (const auto& count : comb)
5767                                                 {
5768                                                         name << (first ? "" : "_") << count;
5769                                                         desc << (first ? "" : ", ") << count;
5770                                                         first = false;
5771                                                 }
5772
5773                                                 name << "_fb_" << fbCount;
5774
5775                                                 if (flag)
5776                                                 {
5777                                                         name << "_unused";
5778                                                         desc << " and unused attachments";
5779                                                 }
5780
5781                                                 const VariableRateTestCase::TestParams params =
5782                                                 {
5783                                                         pipelineConstructionType,       //      PipelineConstructionType        pipelineConstructionType;
5784                                                         true,                                           //      bool                                            nonEmptyFramebuffer;
5785                                                         fbCount,                                        //      vk::VkSampleCountFlagBits       fbCount;
5786                                                         flag,                                           //      bool                                            unusedAttachment;
5787                                                         comb,                                           //      SampleCounts                            subpassCounts;
5788                                                         useFragmentShadingRate,         //      bool                                            useFragmentShadingRate;
5789                                                 };
5790                                                 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
5791                                         }
5792                                 }
5793                         }
5794
5795                         multisampleTests->addChild(variableRateGroup.release());
5796                 }
5797
5798                 {
5799                         de::MovePtr<tcu::TestCaseGroup> mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer"));
5800
5801                         const auto combs = combinations(kSampleCounts, 2);
5802                         for (const auto& comb : combs)
5803                         {
5804                                 // Check different sample count.
5805                                 DE_ASSERT(comb.size() == 2u);
5806                                 const auto& fbCount             = comb[0];
5807                                 const auto& emptyCount  = comb[1];
5808
5809                                 if (fbCount == emptyCount)
5810                                         continue;
5811
5812                                 const std::string fbCountStr    = de::toString(fbCount);
5813                                 const std::string emptyCountStr = de::toString(emptyCount);
5814
5815                                 for (const auto flag : unusedAttachmentFlag)
5816                                 {
5817                                         const std::string nameSuffix    = (flag ? "unused" : "");
5818                                         const std::string descSuffix    = (flag ? "one unused attachment reference" : "no attachment references");
5819                                         const std::string name                  = fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix;
5820                                         const std::string desc                  = "Framebuffer with " + fbCountStr + " samples, subpass with " + emptyCountStr + " samples and " + descSuffix;
5821
5822                                         const VariableRateTestCase::TestParams params
5823                                         {
5824                                                 pipelineConstructionType,                                                       //      PipelineConstructionType        pipelineConstructionType;
5825                                                 true,                                                                                           //      bool                                            nonEmptyFramebuffer;
5826                                                 fbCount,                                                                                        //      vk::VkSampleCountFlagBits       fbCount;
5827                                                 flag,                                                                                           //      bool                                            unusedAttachment;
5828                                                 VariableRateTestCase::SampleCounts(1u, emptyCount),     //      SampleCounts                            subpassCounts;
5829                                                 useFragmentShadingRate,                                                         //      bool                                            useFragmentShadingRate;
5830                                         };
5831                                         mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, desc, params));
5832                                 }
5833                         }
5834
5835                         multisampleTests->addChild(mixedCountGroup.release());
5836                 }
5837         }
5838
5839         return multisampleTests.release();
5840 }
5841
5842 } // pipeline
5843 } // vkt