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