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