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::__anon244b5a740111::SampleMaskWithDepthTestInstance::SampleCoverage884 SampleCoverage() {}
SampleCoveragevkt::pipeline::__anon244b5a740111::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 context.requireDeviceFunctionality("VK_EXT_conservative_rasterization");
1767
1768 const auto& conservativeRasterizationProperties = context.getConservativeRasterizationPropertiesEXT();
1769 const deUint32 subPixelPrecisionBits = context.getDeviceProperties().limits.subPixelPrecisionBits;
1770 const deUint32 subPixelPrecision = (1 << subPixelPrecisionBits);
1771 const float primitiveOverestimationSizeMult = float(subPixelPrecision) * conservativeRasterizationProperties.primitiveOverestimationSize;
1772
1773 DE_ASSERT(subPixelPrecisionBits < sizeof(deUint32) * 8);
1774
1775 if (m_enablePostDepthCoverage)
1776 {
1777 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1778 if (!conservativeRasterizationProperties.conservativeRasterizationPostDepthCoverage)
1779 TCU_THROW(NotSupportedError, "conservativeRasterizationPostDepthCoverage not supported");
1780 }
1781
1782 context.getTestContext().getLog()
1783 << tcu::TestLog::Message
1784 << "maxExtraPrimitiveOverestimationSize=" << conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize << '\n'
1785 << "extraPrimitiveOverestimationSizeGranularity=" << conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity << '\n'
1786 << "degenerateTrianglesRasterized=" << conservativeRasterizationProperties.degenerateTrianglesRasterized << '\n'
1787 << "primitiveOverestimationSize=" << conservativeRasterizationProperties.primitiveOverestimationSize << " (==" << primitiveOverestimationSizeMult << '/' << subPixelPrecision << ")\n"
1788 << tcu::TestLog::EndMessage;
1789
1790
1791 if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
1792 {
1793 if (conservativeRasterizationProperties.extraPrimitiveOverestimationSizeGranularity > conservativeRasterizationProperties.maxExtraPrimitiveOverestimationSize)
1794 TCU_FAIL("Granularity cannot be greater than maximum extra size");
1795 }
1796 else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
1797 {
1798 if (conservativeRasterizationProperties.primitiveUnderestimation == DE_FALSE)
1799 TCU_THROW(NotSupportedError, "Underestimation is not supported");
1800 }
1801 else
1802 TCU_THROW(InternalError, "Non-conservative mode tests are not supported by this class");
1803
1804 if (!conservativeRasterizationProperties.fullyCoveredFragmentShaderInputVariable)
1805 {
1806 TCU_THROW(NotSupportedError, "FullyCoveredEXT input variable is not supported");
1807 }
1808
1809 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1810 }
1811
initPrograms(SourceCollections & programCollection) const1812 void SampleMaskWithConservativeTest::initPrograms(SourceCollections& programCollection) const
1813 {
1814 {
1815 DE_ASSERT((int)m_rasterizationSamples <= 32);
1816
1817 static const char* vertexSource =
1818 "#version 440\n"
1819 "layout(location = 0) in vec4 position;\n"
1820 "layout(location = 1) in vec4 color;\n"
1821 "layout(location = 0) out vec4 vtxColor;\n"
1822 "out gl_PerVertex\n"
1823 "{\n"
1824 " vec4 gl_Position;\n"
1825 "};\n"
1826 "\n"
1827 "void main (void)\n"
1828 "{\n"
1829 " gl_Position = position;\n"
1830 " vtxColor = color;\n"
1831 "}\n";
1832
1833 std::ostringstream fragmentSource;
1834 fragmentSource <<
1835 "#version 440\n"
1836 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "")
1837 << (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT ? "#extension GL_NV_conservative_raster_underestimation : enable\n" : "") <<
1838 "layout(early_fragment_tests) in;\n"
1839 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1840 "layout(location = 0) in vec4 vtxColor;\n"
1841 "layout(location = 0) out vec4 fragColor;\n"
1842 "void main (void)\n"
1843 "{\n";
1844 if (m_enableMinSampleShading)
1845 {
1846 fragmentSource <<
1847 " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1848 " fragColor = vtxColor * (1.0 / " << (int32_t)m_rasterizationSamples << " * coveredSamples);\n";
1849 }
1850 else if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT)
1851 {
1852 fragmentSource <<
1853 " fragColor = gl_FragFullyCoveredNV ? vtxColor : vec4(0.0f);\n";
1854 }
1855 else
1856 {
1857 fragmentSource <<
1858 " fragColor = vtxColor;\n";
1859 }
1860 fragmentSource <<
1861 "}\n";
1862
1863
1864 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1865 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1866 }
1867
1868 {
1869 static const char* vertexSource =
1870 "#version 440\n"
1871 "void main (void)\n"
1872 "{\n"
1873 " const vec4 positions[4] = vec4[4](\n"
1874 " vec4(-1.0, -1.0, 0.0, 1.0),\n"
1875 " vec4(-1.0, 1.0, 0.0, 1.0),\n"
1876 " vec4( 1.0, -1.0, 0.0, 1.0),\n"
1877 " vec4( 1.0, 1.0, 0.0, 1.0)\n"
1878 " );\n"
1879 " gl_Position = positions[gl_VertexIndex];\n"
1880 "}\n";
1881
1882
1883 static const char* fragmentSource =
1884 "#version 440\n"
1885 "precision highp float;\n"
1886 "layout(location = 0) out highp vec4 fragColor;\n"
1887 "layout(set = 0, binding = 0, input_attachment_index = 0) uniform subpassInputMS imageMS;\n"
1888 "layout(push_constant) uniform PushConstantsBlock\n"
1889 "{\n"
1890 " int sampleId;\n"
1891 "} pushConstants;\n"
1892 "void main (void)\n"
1893 "{\n"
1894 " fragColor = subpassLoad(imageMS, pushConstants.sampleId);\n"
1895 "}\n";
1896
1897 programCollection.glslSources.add("quad_vert") << glu::VertexSource(vertexSource);
1898 programCollection.glslSources.add("copy_sample_frag") << glu::FragmentSource(fragmentSource);
1899 }
1900 }
1901
1902
createInstance(Context & context) const1903 TestInstance* SampleMaskWithConservativeTest::createInstance (Context& context) const
1904 {
1905 return new SampleMaskWithConservativeInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enableMinSampleShading, m_minSampleShading, m_enableSampleMask, m_sampleMask,
1906 m_conservativeRasterizationMode, m_enablePostDepthCoverage, true, m_renderType, m_useFragmentShadingRate);
1907 }
1908
1909 // SampleMaskWithDepthTestTest
1910 #ifndef CTS_USES_VULKANSC
SampleMaskWithDepthTestTest(tcu::TestContext & testContext,const std::string & name,const std::string & description,const PipelineConstructionType pipelineConstructionType,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage,const bool useFragmentShadingRate)1911 SampleMaskWithDepthTestTest::SampleMaskWithDepthTestTest (tcu::TestContext& testContext,
1912 const std::string& name,
1913 const std::string& description,
1914 const PipelineConstructionType pipelineConstructionType,
1915 const VkSampleCountFlagBits rasterizationSamples,
1916 const bool enablePostDepthCoverage,
1917 const bool useFragmentShadingRate)
1918 : vkt::TestCase (testContext, name, description)
1919 , m_pipelineConstructionType (pipelineConstructionType)
1920 , m_rasterizationSamples (rasterizationSamples)
1921 , m_enablePostDepthCoverage (enablePostDepthCoverage)
1922 , m_useFragmentShadingRate (useFragmentShadingRate)
1923 {
1924 }
1925
checkSupport(Context & context) const1926 void SampleMaskWithDepthTestTest::checkSupport (Context& context) const
1927 {
1928 if (!context.getDeviceProperties().limits.standardSampleLocations)
1929 TCU_THROW(NotSupportedError, "standardSampleLocations required");
1930
1931 context.requireDeviceFunctionality("VK_EXT_post_depth_coverage");
1932
1933 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1934
1935 if (m_useFragmentShadingRate)
1936 {
1937 if (!context.getFragmentShadingRateProperties().fragmentShadingRateWithShaderSampleMask)
1938 TCU_THROW(NotSupportedError, "fragmentShadingRateWithShaderSampleMask not supported");
1939
1940 if (!checkFragmentShadingRateRequirements(context, m_rasterizationSamples))
1941 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
1942 }
1943 }
1944
initPrograms(SourceCollections & programCollection) const1945 void SampleMaskWithDepthTestTest::initPrograms (SourceCollections& programCollection) const
1946 {
1947 DE_ASSERT((int)m_rasterizationSamples <= 32);
1948
1949 static const char* vertexSource =
1950 "#version 440\n"
1951 "layout(location = 0) in vec4 position;\n"
1952 "layout(location = 1) in vec4 color;\n"
1953 "layout(location = 0) out vec4 vtxColor;\n"
1954 "out gl_PerVertex\n"
1955 "{\n"
1956 " vec4 gl_Position;\n"
1957 "};\n"
1958 "\n"
1959 "void main (void)\n"
1960 "{\n"
1961 " gl_Position = position;\n"
1962 " vtxColor = color;\n"
1963 "}\n";
1964
1965 uint32_t samplesPerFragment = m_rasterizationSamples;
1966 if (m_useFragmentShadingRate)
1967 {
1968 // When FSR coverage is enabled the tests uses a pipeline FSR rate of {2,2},
1969 // which means each fragment shader invocation covers 4 pixels.
1970 samplesPerFragment *= 4;
1971
1972 if (!m_enablePostDepthCoverage)
1973 // For the 4 specific pixels this tests verifies, the primitive
1974 // drawn by the test fully covers 3 of those pixels and
1975 // partially covers 1 of them. When the fragment shader executes
1976 // for those 4 pixels the non-PostDepthCoverage sample mask
1977 // (the sample mask before the depth test) will only have
1978 // 7/8 of the samples set since the last 1/8 is not even covered
1979 // by the primitive.
1980 samplesPerFragment -= m_rasterizationSamples / 2;
1981 }
1982
1983 std::ostringstream fragmentSource;
1984 fragmentSource <<
1985 "#version 440\n"
1986 << (m_enablePostDepthCoverage ? "#extension GL_ARB_post_depth_coverage : require\n" : "") <<
1987 "layout(early_fragment_tests) in;\n"
1988 << (m_enablePostDepthCoverage ? "layout(post_depth_coverage) in;\n" : "") <<
1989 "layout(location = 0) in vec4 vtxColor;\n"
1990 "layout(location = 0) out vec4 fragColor;\n"
1991 "void main (void)\n"
1992 "{\n"
1993 " const int coveredSamples = bitCount(gl_SampleMaskIn[0]);\n"
1994 " fragColor = vtxColor * (1.0 / " << samplesPerFragment << " * coveredSamples);\n"
1995 "}\n";
1996
1997 programCollection.glslSources.add("color_vert") << glu::VertexSource(vertexSource);
1998 programCollection.glslSources.add("color_frag") << glu::FragmentSource(fragmentSource.str());
1999 }
2000
createInstance(Context & context) const2001 TestInstance* SampleMaskWithDepthTestTest::createInstance (Context& context) const
2002 {
2003 return new SampleMaskWithDepthTestInstance(context, m_pipelineConstructionType, m_rasterizationSamples, m_enablePostDepthCoverage, m_useFragmentShadingRate);
2004 }
2005 #endif // CTS_USES_VULKANSC
2006
2007 // RasterizationSamplesInstance
2008
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)2009 RasterizationSamplesInstance::RasterizationSamplesInstance (Context& context,
2010 PipelineConstructionType pipelineConstructionType,
2011 VkPrimitiveTopology topology,
2012 float pointSize,
2013 const std::vector<Vertex4RGBA>& vertices,
2014 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2015 const VkPipelineColorBlendAttachmentState& blendState,
2016 const TestModeFlags modeFlags,
2017 ImageBackingMode backingMode,
2018 const bool useFragmentShadingRate)
2019 : vkt::TestInstance (context)
2020 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2021 , m_renderSize (32, 32)
2022 , m_primitiveTopology (topology)
2023 , m_pointSize (pointSize)
2024 , m_vertices (vertices)
2025 , m_fullQuadVertices (generateVertices(GEOMETRY_TYPE_OPAQUE_QUAD_NONZERO_DEPTH))
2026 , m_modeFlags (modeFlags)
2027 , m_useFragmentShadingRate (useFragmentShadingRate)
2028 {
2029 if (m_modeFlags != 0)
2030 {
2031 const bool useDepth = (m_modeFlags & TEST_MODE_DEPTH_BIT) != 0;
2032 const bool useStencil = (m_modeFlags & TEST_MODE_STENCIL_BIT) != 0;
2033 const VkFormat depthStencilFormat = findSupportedDepthStencilFormat(context, useDepth, useStencil);
2034
2035 if (depthStencilFormat == VK_FORMAT_UNDEFINED)
2036 TCU_THROW(NotSupportedError, "Required depth/stencil format is not supported");
2037
2038 const VkPrimitiveTopology pTopology[2] = { m_primitiveTopology, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP };
2039 const std::vector<Vertex4RGBA> pVertices[2] = { m_vertices, m_fullQuadVertices };
2040
2041 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
2042 new MultisampleRenderer(
2043 context, pipelineConstructionType, m_colorFormat, depthStencilFormat, m_renderSize, useDepth, useStencil,
2044 2u, pTopology, pVertices, multisampleStateParams, blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate));
2045 }
2046 else
2047 {
2048 m_multisampleRenderer = de::MovePtr<MultisampleRenderer>(
2049 new MultisampleRenderer(
2050 context, pipelineConstructionType, m_colorFormat, m_renderSize, topology, vertices, multisampleStateParams,
2051 blendState, RENDER_TYPE_RESOLVE, backingMode, m_useFragmentShadingRate));
2052 }
2053 }
2054
iterate(void)2055 tcu::TestStatus RasterizationSamplesInstance::iterate (void)
2056 {
2057 de::MovePtr<tcu::TextureLevel> level(m_multisampleRenderer->render());
2058 return verifyImage(level->getAccess());
2059 }
2060
verifyImage(const tcu::ConstPixelBufferAccess & result)2061 tcu::TestStatus RasterizationSamplesInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2062 {
2063 // Verify range of unique pixels
2064 {
2065 const deUint32 numUniqueColors = getUniqueColorsCount(result);
2066 const deUint32 minUniqueColors = (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST && m_pointSize == 1.0f) ? 2 : 3;
2067
2068 tcu::TestLog& log = m_context.getTestContext().getLog();
2069
2070 log << tcu::TestLog::Message
2071 << "\nMin. unique colors expected: " << minUniqueColors << "\n"
2072 << "Unique colors found: " << numUniqueColors << "\n"
2073 << tcu::TestLog::EndMessage;
2074
2075 if (numUniqueColors < minUniqueColors)
2076 return tcu::TestStatus::fail("Unique colors out of expected bounds");
2077 }
2078
2079 // Verify shape of the rendered primitive (fuzzy-compare)
2080 {
2081 const tcu::TextureFormat tcuColorFormat = mapVkFormat(m_colorFormat);
2082 const tcu::TextureFormat tcuDepthFormat = tcu::TextureFormat();
2083 const ColorVertexShader vertexShader;
2084 const ColorFragmentShader fragmentShader (tcuColorFormat, tcuDepthFormat);
2085 const rr::Program program (&vertexShader, &fragmentShader);
2086 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, tcuColorFormat, tcuDepthFormat, &program);
2087 rr::RenderState renderState (refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
2088
2089 if (m_primitiveTopology == VK_PRIMITIVE_TOPOLOGY_POINT_LIST)
2090 {
2091 VkPhysicalDeviceProperties deviceProperties;
2092
2093 m_context.getInstanceInterface().getPhysicalDeviceProperties(m_context.getPhysicalDevice(), &deviceProperties);
2094
2095 // gl_PointSize is clamped to pointSizeRange
2096 renderState.point.pointSize = deFloatMin(m_pointSize, deviceProperties.limits.pointSizeRange[1]);
2097 }
2098
2099 if (m_modeFlags == 0)
2100 {
2101 refRenderer.colorClear(tcu::Vec4(0.0f));
2102 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
2103 }
2104 else
2105 {
2106 // For depth/stencil case the primitive is invisible and the surroundings are filled red.
2107 refRenderer.colorClear(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
2108 refRenderer.draw(renderState, mapVkPrimitiveTopology(m_primitiveTopology), m_vertices);
2109 }
2110
2111 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "FuzzyImageCompare", "Image comparison", refRenderer.getAccess(), result, 0.05f, tcu::COMPARE_LOG_RESULT))
2112 return tcu::TestStatus::fail("Primitive has unexpected shape");
2113 }
2114
2115 return tcu::TestStatus::pass("Primitive rendered, unique colors within expected bounds");
2116 }
2117
2118
2119 // MinSampleShadingInstance
2120
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)2121 MinSampleShadingInstance::MinSampleShadingInstance (Context& context,
2122 const PipelineConstructionType pipelineConstructionType,
2123 VkPrimitiveTopology topology,
2124 float pointSize,
2125 const std::vector<Vertex4RGBA>& vertices,
2126 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2127 const VkPipelineColorBlendAttachmentState& colorBlendState,
2128 ImageBackingMode backingMode,
2129 const bool useFragmentShadingRate)
2130 : vkt::TestInstance (context)
2131 , m_pipelineConstructionType(pipelineConstructionType)
2132 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2133 , m_renderSize (32, 32)
2134 , m_primitiveTopology (topology)
2135 , m_vertices (vertices)
2136 , m_multisampleStateParams (multisampleStateParams)
2137 , m_colorBlendState (colorBlendState)
2138 , m_backingMode (backingMode)
2139 , m_useFragmentShadingRate (useFragmentShadingRate)
2140 {
2141 DE_UNREF(pointSize);
2142 }
2143
iterate(void)2144 tcu::TestStatus MinSampleShadingInstance::iterate (void)
2145 {
2146 de::MovePtr<tcu::TextureLevel> noSampleshadingImage;
2147 std::vector<tcu::TextureLevel> sampleShadedImages;
2148
2149 // Render and resolve without sample shading
2150 {
2151 VkPipelineMultisampleStateCreateInfo multisampleStateParms = m_multisampleStateParams;
2152 multisampleStateParms.sampleShadingEnable = VK_FALSE;
2153 multisampleStateParms.minSampleShading = 0.0;
2154
2155 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleStateParms, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2156 noSampleshadingImage = renderer.render();
2157 }
2158
2159 // Render with test minSampleShading and collect per-sample images
2160 {
2161 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_COPY_SAMPLES, m_backingMode, m_useFragmentShadingRate);
2162 renderer.render();
2163
2164 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
2165 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2166 {
2167 sampleShadedImages[sampleId] = *renderer.getSingleSampledImage(sampleId);
2168 }
2169 }
2170
2171 // Log images
2172 {
2173 tcu::TestLog& testLog = m_context.getTestContext().getLog();
2174
2175 testLog << tcu::TestLog::ImageSet("Images", "Images")
2176 << tcu::TestLog::Image("noSampleshadingImage", "Image rendered without sample shading", noSampleshadingImage->getAccess());
2177
2178 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2179 {
2180 testLog << tcu::TestLog::Image("sampleShadedImage", "One sample of sample shaded image", sampleShadedImages[sampleId].getAccess());
2181 }
2182 testLog << tcu::TestLog::EndImageSet;
2183 }
2184
2185 return verifySampleShadedImage(sampleShadedImages, noSampleshadingImage->getAccess());
2186 }
2187
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)2188 tcu::TestStatus MinSampleShadingInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& noSampleshadingImage)
2189 {
2190 const deUint32 pixelCount = noSampleshadingImage.getWidth() * noSampleshadingImage.getHeight() * noSampleshadingImage.getDepth();
2191
2192 bool anyPixelCovered = false;
2193
2194 for (deUint32 pixelNdx = 0; pixelNdx < pixelCount; pixelNdx++)
2195 {
2196 const deUint32 noSampleShadingValue = *((const deUint32*)noSampleshadingImage.getDataPtr() + pixelNdx);
2197
2198 if (noSampleShadingValue == 0)
2199 {
2200 // non-covered pixel, continue
2201 continue;
2202 }
2203 else
2204 {
2205 anyPixelCovered = true;
2206 }
2207
2208 int numNotCoveredSamples = 0;
2209
2210 std::map<deUint32, deUint32> histogram; // map<pixel value, number of occurrences>
2211
2212 // Collect histogram of occurrences or each pixel across all samples
2213 for (size_t i = 0; i < sampleShadedImages.size(); ++i)
2214 {
2215 const deUint32 sampleShadedValue = *((const deUint32*)sampleShadedImages[i].getAccess().getDataPtr() + pixelNdx);
2216
2217 if (sampleShadedValue == 0)
2218 {
2219 numNotCoveredSamples++;
2220 continue;
2221 }
2222
2223 if (histogram.find(sampleShadedValue) != histogram.end())
2224 histogram[sampleShadedValue]++;
2225 else
2226 histogram[sampleShadedValue] = 1;
2227 }
2228
2229 if (numNotCoveredSamples == static_cast<int>(sampleShadedImages.size()))
2230 {
2231 return tcu::TestStatus::fail("Got uncovered pixel, where covered samples were expected");
2232 }
2233
2234 const int uniqueColorsCount = (int)histogram.size();
2235 const int expectedUniqueSamplesCount = static_cast<int>(m_multisampleStateParams.minSampleShading * static_cast<float>(sampleShadedImages.size()) + 0.5f);
2236
2237 if (uniqueColorsCount + numNotCoveredSamples < expectedUniqueSamplesCount)
2238 {
2239 return tcu::TestStatus::fail("Got less unique colors than requested through minSampleShading");
2240 }
2241 }
2242
2243 if (!anyPixelCovered)
2244 {
2245 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShading");
2246 }
2247
2248 return tcu::TestStatus::pass("Got proper count of unique colors");
2249 }
2250
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)2251 MinSampleShadingDisabledInstance::MinSampleShadingDisabledInstance (Context& context,
2252 const PipelineConstructionType pipelineConstructionType,
2253 VkPrimitiveTopology topology,
2254 float pointSize,
2255 const std::vector<Vertex4RGBA>& vertices,
2256 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2257 const VkPipelineColorBlendAttachmentState& blendState,
2258 ImageBackingMode backingMode,
2259 const bool useFragmentShadingRate)
2260 : MinSampleShadingInstance (context, pipelineConstructionType, topology, pointSize, vertices, multisampleStateParams, blendState, backingMode, useFragmentShadingRate)
2261 {
2262 }
2263
verifySampleShadedImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & noSampleshadingImage)2264 tcu::TestStatus MinSampleShadingDisabledInstance::verifySampleShadedImage (const std::vector<tcu::TextureLevel>& sampleShadedImages,
2265 const tcu::ConstPixelBufferAccess& noSampleshadingImage)
2266 {
2267 const deUint32 samplesCount = (int)sampleShadedImages.size();
2268 const deUint32 width = noSampleshadingImage.getWidth();
2269 const deUint32 height = noSampleshadingImage.getHeight();
2270 const deUint32 depth = noSampleshadingImage.getDepth();
2271 const tcu::UVec4 zeroPixel = tcu::UVec4();
2272 bool anyPixelCovered = false;
2273
2274 DE_ASSERT(depth == 1);
2275 DE_UNREF(depth);
2276
2277 for (deUint32 y = 0; y < height; ++y)
2278 for (deUint32 x = 0; x < width; ++x)
2279 {
2280 const tcu::UVec4 noSampleShadingValue = noSampleshadingImage.getPixelUint(x, y);
2281
2282 if (noSampleShadingValue == zeroPixel)
2283 continue;
2284
2285 anyPixelCovered = true;
2286 tcu::UVec4 sampleShadingValue = tcu::UVec4();
2287
2288 // Collect histogram of occurrences or each pixel across all samples
2289 for (size_t i = 0; i < samplesCount; ++i)
2290 {
2291 const tcu::UVec4 sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y);
2292
2293 sampleShadingValue += sampleShadedValue;
2294 }
2295
2296 sampleShadingValue = sampleShadingValue / samplesCount;
2297
2298 if (sampleShadingValue.w() != 255)
2299 {
2300 return tcu::TestStatus::fail("Invalid Alpha channel value");
2301 }
2302
2303 if (sampleShadingValue != noSampleShadingValue)
2304 {
2305 return tcu::TestStatus::fail("Invalid color");
2306 }
2307 }
2308
2309 if (!anyPixelCovered)
2310 {
2311 return tcu::TestStatus::fail("Did not get any covered pixel, cannot test minSampleShadingDisabled");
2312 }
2313
2314 return tcu::TestStatus::pass("Got proper count of unique colors");
2315 }
2316
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)2317 SampleMaskInstance::SampleMaskInstance (Context& context,
2318 const PipelineConstructionType pipelineConstructionType,
2319 VkPrimitiveTopology topology,
2320 float pointSize,
2321 const std::vector<Vertex4RGBA>& vertices,
2322 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2323 const VkPipelineColorBlendAttachmentState& blendState,
2324 ImageBackingMode backingMode,
2325 const bool useFragmentShadingRate)
2326 : vkt::TestInstance (context)
2327 , m_pipelineConstructionType(pipelineConstructionType)
2328 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2329 , m_renderSize (32, 32)
2330 , m_primitiveTopology (topology)
2331 , m_vertices (vertices)
2332 , m_multisampleStateParams (multisampleStateParams)
2333 , m_colorBlendState (blendState)
2334 , m_backingMode (backingMode)
2335 , m_useFragmentShadingRate (useFragmentShadingRate)
2336 {
2337 DE_UNREF(pointSize);
2338 }
2339
iterate(void)2340 tcu::TestStatus SampleMaskInstance::iterate (void)
2341 {
2342 de::MovePtr<tcu::TextureLevel> testSampleMaskImage;
2343 de::MovePtr<tcu::TextureLevel> minSampleMaskImage;
2344 de::MovePtr<tcu::TextureLevel> maxSampleMaskImage;
2345
2346 // Render with test flags
2347 {
2348 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2349 testSampleMaskImage = renderer.render();
2350 }
2351
2352 // Render with all flags off
2353 {
2354 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
2355 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, (VkSampleMask)0);
2356
2357 multisampleParams.pSampleMask = sampleMask.data();
2358
2359 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2360 minSampleMaskImage = renderer.render();
2361 }
2362
2363 // Render with all flags on
2364 {
2365 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
2366 const std::vector<VkSampleMask> sampleMask (multisampleParams.rasterizationSamples / 32, ~((VkSampleMask)0));
2367
2368 multisampleParams.pSampleMask = sampleMask.data();
2369
2370 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2371 maxSampleMaskImage = renderer.render();
2372 }
2373
2374 return verifyImage(testSampleMaskImage->getAccess(), minSampleMaskImage->getAccess(), maxSampleMaskImage->getAccess());
2375 }
2376
verifyImage(const tcu::ConstPixelBufferAccess & testSampleMaskImage,const tcu::ConstPixelBufferAccess & minSampleMaskImage,const tcu::ConstPixelBufferAccess & maxSampleMaskImage)2377 tcu::TestStatus SampleMaskInstance::verifyImage (const tcu::ConstPixelBufferAccess& testSampleMaskImage,
2378 const tcu::ConstPixelBufferAccess& minSampleMaskImage,
2379 const tcu::ConstPixelBufferAccess& maxSampleMaskImage)
2380 {
2381 const deUint32 testColorCount = getUniqueColorsCount(testSampleMaskImage);
2382 const deUint32 minColorCount = getUniqueColorsCount(minSampleMaskImage);
2383 const deUint32 maxColorCount = getUniqueColorsCount(maxSampleMaskImage);
2384
2385 tcu::TestLog& log = m_context.getTestContext().getLog();
2386
2387 log << tcu::TestLog::Message
2388 << "\nColors found: " << testColorCount << "\n"
2389 << "Min. colors expected: " << minColorCount << "\n"
2390 << "Max. colors expected: " << maxColorCount << "\n"
2391 << tcu::TestLog::EndMessage;
2392
2393 if (minColorCount > testColorCount || testColorCount > maxColorCount)
2394 return tcu::TestStatus::fail("Unique colors out of expected bounds");
2395 else
2396 return tcu::TestStatus::pass("Unique colors within expected bounds");
2397 }
2398 #ifndef CTS_USES_VULKANSC
testRasterSamplesConsistency(Context & context,MultisampleTestParams params)2399 tcu::TestStatus testRasterSamplesConsistency (Context& context, MultisampleTestParams params)
2400 {
2401 const VkSampleCountFlagBits samples[] =
2402 {
2403 VK_SAMPLE_COUNT_1_BIT,
2404 VK_SAMPLE_COUNT_2_BIT,
2405 VK_SAMPLE_COUNT_4_BIT,
2406 VK_SAMPLE_COUNT_8_BIT,
2407 VK_SAMPLE_COUNT_16_BIT,
2408 VK_SAMPLE_COUNT_32_BIT,
2409 VK_SAMPLE_COUNT_64_BIT
2410 };
2411
2412 const Vertex4RGBA vertexData[3] =
2413 {
2414 {
2415 tcu::Vec4(-0.75f, 0.0f, 0.0f, 1.0f),
2416 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2417 },
2418 {
2419 tcu::Vec4(0.75f, 0.125f, 0.0f, 1.0f),
2420 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2421 },
2422 {
2423 tcu::Vec4(0.75f, -0.125f, 0.0f, 1.0f),
2424 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)
2425 }
2426 };
2427
2428 const std::vector<Vertex4RGBA> vertices (vertexData, vertexData + 3);
2429 deUint32 prevUniqueColors = 2;
2430 int renderCount = 0;
2431
2432 // Do not render with 1 sample (start with samplesNdx = 1).
2433 for (int samplesNdx = 1; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
2434 {
2435 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), samples[samplesNdx]))
2436 continue;
2437
2438 if (params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, samples[samplesNdx]))
2439 continue;
2440
2441 const VkPipelineMultisampleStateCreateInfo multisampleStateParams
2442 {
2443 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2444 DE_NULL, // const void* pNext;
2445 0u, // VkPipelineMultisampleStateCreateFlags flags;
2446 samples[samplesNdx], // VkSampleCountFlagBits rasterizationSamples;
2447 false, // VkBool32 sampleShadingEnable;
2448 0.0f, // float minSampleShading;
2449 DE_NULL, // const VkSampleMask* pSampleMask;
2450 false, // VkBool32 alphaToCoverageEnable;
2451 false // VkBool32 alphaToOneEnable;
2452 };
2453
2454 MultisampleRenderer renderer (context, params.pipelineConstructionType, VK_FORMAT_R8G8B8A8_UNORM, tcu::IVec2(32, 32), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, vertices, multisampleStateParams, getDefaultColorBlendAttachmentState(), RENDER_TYPE_RESOLVE, params.backingMode, params.useFragmentShadingRate);
2455 de::MovePtr<tcu::TextureLevel> result = renderer.render();
2456 const deUint32 uniqueColors = getUniqueColorsCount(result->getAccess());
2457
2458 renderCount++;
2459
2460 if (prevUniqueColors > uniqueColors)
2461 {
2462 std::ostringstream message;
2463
2464 message << "More unique colors generated with " << samples[samplesNdx - 1] << " than with " << samples[samplesNdx];
2465 return tcu::TestStatus::fail(message.str());
2466 }
2467
2468 prevUniqueColors = uniqueColors;
2469 }
2470
2471 if (renderCount == 0)
2472 {
2473 if (params.useFragmentShadingRate && !context.getFragmentShadingRateFeatures().pipelineFragmentShadingRate)
2474 TCU_THROW(NotSupportedError, "pipelineFragmentShadingRate is unsupported");
2475 TCU_THROW(NotSupportedError, "Multisampling is unsupported");
2476 }
2477
2478 return tcu::TestStatus::pass("Number of unique colors increases as the sample count increases");
2479 }
2480 #endif // CTS_USES_VULKANSC
2481
2482 // AlphaToOneInstance
2483
AlphaToOneInstance(Context & context,const PipelineConstructionType pipelineConstructionType,VkPrimitiveTopology topology,const std::vector<Vertex4RGBA> & vertices,const VkPipelineMultisampleStateCreateInfo & multisampleStateParams,const VkPipelineColorBlendAttachmentState & blendState,ImageBackingMode backingMode,const bool useFragmentShadingRate)2484 AlphaToOneInstance::AlphaToOneInstance (Context& context,
2485 const PipelineConstructionType pipelineConstructionType,
2486 VkPrimitiveTopology topology,
2487 const std::vector<Vertex4RGBA>& vertices,
2488 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2489 const VkPipelineColorBlendAttachmentState& blendState,
2490 ImageBackingMode backingMode,
2491 const bool useFragmentShadingRate)
2492 : vkt::TestInstance (context)
2493 , m_pipelineConstructionType(pipelineConstructionType)
2494 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2495 , m_renderSize (32, 32)
2496 , m_primitiveTopology (topology)
2497 , m_vertices (vertices)
2498 , m_multisampleStateParams (multisampleStateParams)
2499 , m_colorBlendState (blendState)
2500 , m_backingMode (backingMode)
2501 , m_useFragmentShadingRate (useFragmentShadingRate)
2502 {
2503 }
2504
iterate(void)2505 tcu::TestStatus AlphaToOneInstance::iterate (void)
2506 {
2507 DE_ASSERT(m_multisampleStateParams.alphaToOneEnable);
2508 DE_ASSERT(m_colorBlendState.blendEnable);
2509
2510 de::MovePtr<tcu::TextureLevel> alphaOneImage;
2511 de::MovePtr<tcu::TextureLevel> noAlphaOneImage;
2512
2513 RenderType renderType = m_multisampleStateParams.rasterizationSamples == vk::VK_SAMPLE_COUNT_1_BIT ? RENDER_TYPE_SINGLE_SAMPLE : RENDER_TYPE_RESOLVE;
2514
2515 // Render with blend enabled and alpha to one on
2516 {
2517 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate);
2518 alphaOneImage = renderer.render();
2519 }
2520
2521 // Render with blend enabled and alpha to one off
2522 {
2523 VkPipelineMultisampleStateCreateInfo multisampleParams = m_multisampleStateParams;
2524 multisampleParams.alphaToOneEnable = false;
2525
2526 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, multisampleParams, m_colorBlendState, renderType, m_backingMode, m_useFragmentShadingRate);
2527 noAlphaOneImage = renderer.render();
2528 }
2529
2530 return verifyImage(alphaOneImage->getAccess(), noAlphaOneImage->getAccess());
2531 }
2532
verifyImage(const tcu::ConstPixelBufferAccess & alphaOneImage,const tcu::ConstPixelBufferAccess & noAlphaOneImage)2533 tcu::TestStatus AlphaToOneInstance::verifyImage (const tcu::ConstPixelBufferAccess& alphaOneImage,
2534 const tcu::ConstPixelBufferAccess& noAlphaOneImage)
2535 {
2536 for (int y = 0; y < m_renderSize.y(); y++)
2537 {
2538 for (int x = 0; x < m_renderSize.x(); x++)
2539 {
2540 if (alphaOneImage.getPixel(x, y).w() != 1.0)
2541 {
2542 std::ostringstream message;
2543 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " doesn't have alpha set to 1";
2544 return tcu::TestStatus::fail(message.str());
2545 }
2546
2547 if (!tcu::boolAll(tcu::greaterThanEqual(alphaOneImage.getPixel(x, y), noAlphaOneImage.getPixel(x, y))))
2548 {
2549 std::ostringstream message;
2550 message << "Unsatisfied condition: " << alphaOneImage.getPixel(x, y) << " >= " << noAlphaOneImage.getPixel(x, y);
2551 return tcu::TestStatus::fail(message.str());
2552 }
2553 }
2554 }
2555
2556 return tcu::TestStatus::pass("Image rendered with alpha-to-one contains pixels of image rendered with no alpha-to-one");
2557 }
2558
2559
2560 // AlphaToCoverageInstance
2561
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)2562 AlphaToCoverageInstance::AlphaToCoverageInstance (Context& context,
2563 const PipelineConstructionType pipelineConstructionType,
2564 VkPrimitiveTopology topology,
2565 const std::vector<Vertex4RGBA>& vertices,
2566 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2567 const VkPipelineColorBlendAttachmentState& blendState,
2568 GeometryType geometryType,
2569 ImageBackingMode backingMode,
2570 const bool useFragmentShadingRate)
2571 : vkt::TestInstance (context)
2572 , m_pipelineConstructionType(pipelineConstructionType)
2573 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2574 , m_renderSize (32, 32)
2575 , m_primitiveTopology (topology)
2576 , m_vertices (vertices)
2577 , m_multisampleStateParams (multisampleStateParams)
2578 , m_colorBlendState (blendState)
2579 , m_geometryType (geometryType)
2580 , m_backingMode (backingMode)
2581 , m_useFragmentShadingRate (useFragmentShadingRate)
2582 {
2583 }
2584
iterate(void)2585 tcu::TestStatus AlphaToCoverageInstance::iterate (void)
2586 {
2587 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2588
2589 de::MovePtr<tcu::TextureLevel> result;
2590 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_RESOLVE, m_backingMode, m_useFragmentShadingRate);
2591
2592 result = renderer.render();
2593
2594 return verifyImage(result->getAccess());
2595 }
2596
verifyImage(const tcu::ConstPixelBufferAccess & result)2597 tcu::TestStatus AlphaToCoverageInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2598 {
2599 float maxColorValue;
2600
2601 switch (m_geometryType)
2602 {
2603 case GEOMETRY_TYPE_OPAQUE_QUAD:
2604 maxColorValue = 1.01f;
2605 break;
2606
2607 case GEOMETRY_TYPE_TRANSLUCENT_QUAD:
2608 maxColorValue = 0.52f;
2609 break;
2610
2611 case GEOMETRY_TYPE_INVISIBLE_QUAD:
2612 maxColorValue = 0.01f;
2613 break;
2614
2615 default:
2616 maxColorValue = 0.0f;
2617 DE_ASSERT(false);
2618 }
2619
2620 for (int y = 0; y < m_renderSize.y(); y++)
2621 {
2622 for (int x = 0; x < m_renderSize.x(); x++)
2623 {
2624 if (result.getPixel(x, y).x() > maxColorValue)
2625 {
2626 std::ostringstream message;
2627 message << "Pixel is not below the threshold value (" << result.getPixel(x, y).x() << " > " << maxColorValue << ")";
2628 return tcu::TestStatus::fail(message.str());
2629 }
2630 }
2631 }
2632
2633 return tcu::TestStatus::pass("Image matches reference value");
2634 }
2635
2636 // AlphaToCoverageNoColorAttachmentInstance
2637
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)2638 AlphaToCoverageNoColorAttachmentInstance::AlphaToCoverageNoColorAttachmentInstance (Context& context,
2639 const PipelineConstructionType pipelineConstructionType,
2640 VkPrimitiveTopology topology,
2641 const std::vector<Vertex4RGBA>& vertices,
2642 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2643 const VkPipelineColorBlendAttachmentState& blendState,
2644 GeometryType geometryType,
2645 ImageBackingMode backingMode,
2646 const bool useFragmentShadingRate)
2647 : vkt::TestInstance (context)
2648 , m_pipelineConstructionType(pipelineConstructionType)
2649 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2650 , m_depthStencilFormat (VK_FORMAT_D16_UNORM)
2651 , m_renderSize (32, 32)
2652 , m_primitiveTopology (topology)
2653 , m_vertices (vertices)
2654 , m_multisampleStateParams (multisampleStateParams)
2655 , m_colorBlendState (blendState)
2656 , m_geometryType (geometryType)
2657 , m_backingMode (backingMode)
2658 , m_useFragmentShadingRate (useFragmentShadingRate)
2659 {
2660 }
2661
iterate(void)2662 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::iterate (void)
2663 {
2664 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2665
2666 de::MovePtr<tcu::TextureLevel> result;
2667 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, true, false, 1u, &m_primitiveTopology, &m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_DEPTHSTENCIL_ONLY, m_backingMode, m_useFragmentShadingRate, 1.0f);
2668
2669 result = renderer.render();
2670
2671 return verifyImage(result->getAccess());
2672 }
2673
verifyImage(const tcu::ConstPixelBufferAccess & result)2674 tcu::TestStatus AlphaToCoverageNoColorAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2675 {
2676 for (int y = 0; y < m_renderSize.y(); y++)
2677 {
2678 for (int x = 0; x < m_renderSize.x(); x++)
2679 {
2680 // Expect full red for each pixel. Fail if clear color is showing.
2681 if (result.getPixel(x, y).x() < 1.0f)
2682 {
2683 // Log result image when failing.
2684 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2685
2686 return tcu::TestStatus::fail("Fail");
2687 }
2688 }
2689 }
2690
2691 return tcu::TestStatus::pass("Pass");
2692 }
2693
2694 // AlphaToCoverageColorUnusedAttachmentInstance
2695
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)2696 AlphaToCoverageColorUnusedAttachmentInstance::AlphaToCoverageColorUnusedAttachmentInstance (Context& context,
2697 const PipelineConstructionType pipelineConstructionType,
2698 VkPrimitiveTopology topology,
2699 const std::vector<Vertex4RGBA>& vertices,
2700 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
2701 const VkPipelineColorBlendAttachmentState& blendState,
2702 GeometryType geometryType,
2703 ImageBackingMode backingMode,
2704 const bool useFragmentShadingRate)
2705 : vkt::TestInstance (context)
2706 , m_pipelineConstructionType (pipelineConstructionType)
2707 , m_colorFormat (VK_FORMAT_R5G6B5_UNORM_PACK16)
2708 , m_renderSize (32, 32)
2709 , m_primitiveTopology (topology)
2710 , m_vertices (vertices)
2711 , m_multisampleStateParams (multisampleStateParams)
2712 , m_colorBlendState (blendState)
2713 , m_geometryType (geometryType)
2714 , m_backingMode (backingMode)
2715 , m_useFragmentShadingRate (useFragmentShadingRate)
2716 {
2717 }
2718
iterate(void)2719 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::iterate (void)
2720 {
2721 DE_ASSERT(m_multisampleStateParams.alphaToCoverageEnable);
2722
2723 de::MovePtr<tcu::TextureLevel> result;
2724 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, m_primitiveTopology, m_vertices, m_multisampleStateParams, m_colorBlendState, RENDER_TYPE_UNUSED_ATTACHMENT, m_backingMode, m_useFragmentShadingRate);
2725
2726 result = renderer.render();
2727
2728 return verifyImage(result->getAccess());
2729 }
2730
verifyImage(const tcu::ConstPixelBufferAccess & result)2731 tcu::TestStatus AlphaToCoverageColorUnusedAttachmentInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
2732 {
2733 for (int y = 0; y < m_renderSize.y(); y++)
2734 {
2735 for (int x = 0; x < m_renderSize.x(); x++)
2736 {
2737 // Quad color gets written to color buffer at location 1, and the alpha value to location 0 which is unused.
2738 // The coverage should still be affected by the alpha written to location 0.
2739 if ((m_geometryType == GEOMETRY_TYPE_OPAQUE_QUAD && result.getPixel(x, y).x() < 1.0f)
2740 || (m_geometryType == GEOMETRY_TYPE_INVISIBLE_QUAD && result.getPixel(x, y).x() > 0.0f))
2741 {
2742 // Log result image when failing.
2743 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result image") << tcu::TestLog::Image("Rendered", "Rendered image", result) << tcu::TestLog::EndImageSet;
2744
2745 return tcu::TestStatus::fail("Fail");
2746 }
2747 }
2748 }
2749
2750 return tcu::TestStatus::pass("Pass");
2751 }
2752
2753 // SampleMaskWithConservativeInstance
2754
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)2755 SampleMaskWithConservativeInstance::SampleMaskWithConservativeInstance (Context& context,
2756 const PipelineConstructionType pipelineConstructionType,
2757 const VkSampleCountFlagBits rasterizationSamples,
2758 const bool enableMinSampleShading,
2759 const float minSampleShading,
2760 const bool enableSampleMask,
2761 const VkSampleMask sampleMask,
2762 const VkConservativeRasterizationModeEXT conservativeRasterizationMode,
2763 const bool enablePostDepthCoverage,
2764 const bool enableFullyCoveredEXT,
2765 const RenderType renderType,
2766 const bool useFragmentShadingRate)
2767 : vkt::TestInstance (context)
2768 , m_pipelineConstructionType (pipelineConstructionType)
2769 , m_rasterizationSamples (rasterizationSamples)
2770 , m_enablePostDepthCoverage (enablePostDepthCoverage)
2771 , m_enableFullyCoveredEXT (enableFullyCoveredEXT)
2772 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
2773 , m_depthStencilFormat (VK_FORMAT_D16_UNORM)
2774 , m_renderSize (tcu::IVec2(10, 10))
2775 , m_useDepth (true)
2776 , m_useStencil (false)
2777 , m_useConservative (true)
2778 , m_useFragmentShadingRate (useFragmentShadingRate)
2779 , m_conservativeRasterizationMode (conservativeRasterizationMode)
2780 , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
2781 , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
2782 , m_depthClearValue (0.5f)
2783 , m_vertices (generateVertices())
2784 , m_enableSampleMask (enableSampleMask)
2785 , m_sampleMask (std::vector<VkSampleMask>{sampleMask})
2786 , m_enableMinSampleShading (enableMinSampleShading)
2787 , m_minSampleShading (minSampleShading)
2788 , m_multisampleStateParams (getMultisampleState(rasterizationSamples, enableMinSampleShading, minSampleShading, enableSampleMask))
2789 , m_rasterizationConservativeStateCreateInfo (getRasterizationConservativeStateCreateInfo(conservativeRasterizationMode))
2790 , m_blendState (getDefaultColorBlendAttachmentState())
2791 , m_renderType (renderType)
2792 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR)
2793 {
2794 }
2795
iterate(void)2796 tcu::TestStatus SampleMaskWithConservativeInstance::iterate (void)
2797 {
2798
2799 de::MovePtr<tcu::TextureLevel> noSampleshadingImage;
2800 std::vector<tcu::TextureLevel> sampleShadedImages;
2801
2802 {
2803 MultisampleRenderer renderer(m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, m_useConservative, m_useFragmentShadingRate, 1u,
2804 &m_topology, &m_vertices, m_multisampleStateParams, m_blendState, m_rasterizationConservativeStateCreateInfo, RENDER_TYPE_RESOLVE, m_imageBackingMode, m_depthClearValue);
2805 noSampleshadingImage = renderer.render();
2806 }
2807
2808 {
2809 const VkPipelineColorBlendAttachmentState colorBlendState =
2810 {
2811 false, // VkBool32 blendEnable;
2812 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
2813 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
2814 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
2815 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
2816 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
2817 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
2818 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
2819 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
2820 };
2821
2822 MultisampleRenderer mRenderer (m_context, m_pipelineConstructionType, m_colorFormat, m_renderSize, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, m_vertices, m_multisampleStateParams, colorBlendState, RENDER_TYPE_COPY_SAMPLES, IMAGE_BACKING_MODE_REGULAR, m_useFragmentShadingRate);
2823 mRenderer.render();
2824
2825 sampleShadedImages.resize(m_multisampleStateParams.rasterizationSamples);
2826 for (deUint32 sampleId = 0; sampleId < sampleShadedImages.size(); sampleId++)
2827 {
2828 sampleShadedImages[sampleId] = *mRenderer.getSingleSampledImage(sampleId);
2829 }
2830
2831 }
2832
2833 return verifyImage(sampleShadedImages, noSampleshadingImage->getAccess());
2834 }
2835
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples,const bool enableMinSampleShading,const float minSampleShading,const bool enableSampleMask)2836 VkPipelineMultisampleStateCreateInfo SampleMaskWithConservativeInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples, const bool enableMinSampleShading, const float minSampleShading, const bool enableSampleMask)
2837 {
2838 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
2839 {
2840 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
2841 DE_NULL, // const void* pNext;
2842 0u, // VkPipelineMultisampleStateCreateFlags flags;
2843 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
2844 enableMinSampleShading ? VK_TRUE : VK_FALSE, // VkBool32 sampleShadingEnable;
2845 enableMinSampleShading ? minSampleShading : 0.0f, // float minSampleShading;
2846 enableSampleMask ? m_sampleMask.data() : DE_NULL, // const VkSampleMask* pSampleMask;
2847 false, // VkBool32 alphaToCoverageEnable;
2848 false // VkBool32 alphaToOneEnable;
2849 };
2850
2851 return multisampleStateParams;
2852 }
2853
getRasterizationConservativeStateCreateInfo(const VkConservativeRasterizationModeEXT conservativeRasterizationMode)2854 VkPipelineRasterizationConservativeStateCreateInfoEXT SampleMaskWithConservativeInstance::getRasterizationConservativeStateCreateInfo(const VkConservativeRasterizationModeEXT conservativeRasterizationMode)
2855 {
2856 const VkPipelineRasterizationConservativeStateCreateInfoEXT rasterizationConservativeStateCreateInfo =
2857 {
2858 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT, // VkStructureType sType;
2859 DE_NULL, // const void* pNext;
2860 (VkPipelineRasterizationConservativeStateCreateFlagsEXT)0, // VkPipelineRasterizationConservativeStateCreateFlagsEXT flags;
2861 conservativeRasterizationMode, // VkConservativeRasterizationModeEXT conservativeRasterizationMode;
2862 0.0f // float extraPrimitiveOverestimationSize;
2863 };
2864
2865 return rasterizationConservativeStateCreateInfo;
2866 }
2867
generateVertices(void)2868 std::vector<Vertex4RGBA> SampleMaskWithConservativeInstance::generateVertices (void)
2869 {
2870 std::vector<Vertex4RGBA> vertices;
2871
2872 {
2873 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
2874 vertices.push_back(vertexInput);
2875 }
2876 {
2877 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
2878 vertices.push_back(vertexInput);
2879 }
2880 {
2881 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 0.0f, 1.0f), m_renderColor };
2882 vertices.push_back(vertexInput);
2883 }
2884
2885 return vertices;
2886 }
2887
verifyImage(const std::vector<tcu::TextureLevel> & sampleShadedImages,const tcu::ConstPixelBufferAccess & result)2888 tcu::TestStatus SampleMaskWithConservativeInstance::verifyImage (const std::vector<tcu::TextureLevel>& sampleShadedImages, const tcu::ConstPixelBufferAccess& result)
2889 {
2890 bool pass = true;
2891 const int width = result.getWidth();
2892 const int height = result.getHeight();
2893 tcu::TestLog& log = m_context.getTestContext().getLog();
2894
2895 const deUint32 samplesCount = (int)sampleShadedImages.size();
2896
2897 for (size_t i = 0; i < samplesCount; ++i)
2898 {
2899 const tcu::ConstPixelBufferAccess &s = sampleShadedImages[i].getAccess();
2900
2901 log << tcu::TestLog::ImageSet("Per sample image", "Per sampe image")
2902 << tcu::TestLog::Image("Layer", "Layer", s)
2903 << tcu::TestLog::EndImageSet;
2904 }
2905
2906 // Leave sample count intact (return 1) if multiplication by minSampleShading won't exceed base 2
2907 // otherwise round up to the nearest power of 2
2908 auto sampleCountDivider = [](float x) {
2909 float power = 1.0;
2910 while (power < x)
2911 {
2912 power *= 2;
2913 }
2914 return power;
2915 };
2916
2917 DE_ASSERT(width == 10);
2918 DE_ASSERT(height == 10);
2919
2920 const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
2921 std::vector<std::pair<int, int>> fullyCoveredPixelsCoordinateSet;
2922
2923 // Generating set of pixel coordinate values covered by the triangle
2924 if (m_conservativeRasterizationMode == VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT)
2925 {
2926 for (int i = 0; i < width; i++)
2927 {
2928 for (int j = 0; j < height; j++)
2929 {
2930 // Rasterization will cover half of the triangle plus 1 pixel edge due to the overeestimation
2931 if (i < 5 && i + j < 11)
2932 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2933 }
2934 }
2935 }
2936 else
2937 {
2938 if (m_useFragmentShadingRate && !m_enableMinSampleShading)
2939 {
2940 // When m_enableMinSampleShading is not enabled shader uses gl_FragFullyCoveredNV.
2941 // Additionaly when FSR coverage is enabled the tests uses a pipeline FSR rate of { 2,2 }
2942 // and as a result rasterization will cover only four pixels due to the underestimation.
2943 for (int i = 2; i < 4; i++)
2944 for (int j = 2; j < 4; j++)
2945 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2946 }
2947 else
2948 {
2949 for (int i = 1; i < width; i++)
2950 {
2951 for (int j = 1; j < height; j++)
2952 {
2953 // Rasterization will cover half of the triangle minus 1 pixel edge due to the underestimation
2954 if (i < 5 && i + j < 8)
2955 fullyCoveredPixelsCoordinateSet.push_back(std::make_pair(i, j));
2956 }
2957 }
2958 }
2959 }
2960
2961 for (int x = 0; x < width; ++x)
2962 for (int y = 0; y < height; ++y)
2963 {
2964 const tcu::Vec4 resultPixel = result.getPixel(x, y);
2965
2966 if (std::find(fullyCoveredPixelsCoordinateSet.begin(), fullyCoveredPixelsCoordinateSet.end(), std::make_pair(x, y)) != fullyCoveredPixelsCoordinateSet.end())
2967 {
2968 if (m_enableMinSampleShading)
2969 {
2970 tcu::UVec4 sampleShadingValue = tcu::UVec4();
2971 for (size_t i = 0; i < samplesCount; ++i)
2972 {
2973 const tcu::UVec4 sampleShadedValue = sampleShadedImages[i].getAccess().getPixelUint(x, y);
2974
2975 sampleShadingValue += sampleShadedValue;
2976 }
2977
2978 //Calculate coverage of a single sample Image based on accumulated value from the whole set
2979 int sampleCoverageValue = sampleShadingValue.w() / samplesCount;
2980 //Calculates an estimated coverage value based on the number of samples and the minimumSampleShading
2981 int expectedCovergaveValue = (int)(255.0 / sampleCountDivider((float)m_rasterizationSamples * m_minSampleShading)) + 1;
2982
2983 //The specification allows for larger sample count than minimum value, however resulted coverage should never be lower than minimum
2984 if (sampleCoverageValue > expectedCovergaveValue)
2985 {
2986 log << tcu::TestLog::Message << "Coverage value " << sampleCoverageValue << " greather than expected: " << expectedCovergaveValue << tcu::TestLog::EndMessage;
2987
2988 pass = false;
2989 }
2990 }
2991 else if (m_enableSampleMask)
2992 {
2993 // Sample mask with all bits on will not affect fragment coverage
2994 if (m_sampleMask[0] == 0xFFFFFFFF)
2995 {
2996 if (resultPixel != m_renderColor)
2997 {
2998 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
2999 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
3000
3001 pass = false;
3002 }
3003 }
3004 // Sample mask with half bits off will reduce sample coverage by half
3005 else if (m_sampleMask[0] == 0xAAAAAAAA)
3006 {
3007
3008 const tcu::Vec4 renderColorHalfOpacity(0.0f, 0.5f, 0.0f, 0.5f);
3009 const float threshold = 0.02f;
3010
3011 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3012 {
3013 if ((renderColorHalfOpacity[componentNdx] != 0.0f && resultPixel[componentNdx] <= (renderColorHalfOpacity[componentNdx] - threshold))
3014 || resultPixel[componentNdx] >= (renderColorHalfOpacity[componentNdx] + threshold))
3015 {
3016 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3017 << " Reference: " << renderColorHalfOpacity << " +/- " << threshold << tcu::TestLog::EndMessage;
3018
3019 pass = false;
3020 }
3021 }
3022 }
3023 // Sample mask with all bits off will cause all fragment to failed opacity test
3024 else if (m_sampleMask[0] == 0x00000000)
3025 {
3026 if (resultPixel != clearColor)
3027 {
3028 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3029 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3030
3031 pass = false;
3032 }
3033 }
3034 else
3035 {
3036 log << tcu::TestLog::Message << "Unexpected sample mask value" << tcu::TestLog::EndMessage;
3037
3038 pass = false;
3039 }
3040 }
3041 else
3042 {
3043 if (resultPixel != m_renderColor)
3044 {
3045 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3046 << " Reference: " << m_renderColor << tcu::TestLog::EndMessage;
3047
3048 pass = false;
3049 }
3050 }
3051 }
3052 else
3053 {
3054 if (resultPixel != clearColor)
3055 {
3056 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3057 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3058
3059 pass = false;
3060 }
3061 }
3062 }
3063
3064 if (pass)
3065 return tcu::TestStatus::pass("Passed");
3066 else
3067 {
3068 log << tcu::TestLog::ImageSet("LayerContent", "Layer content")
3069 << tcu::TestLog::Image("Layer", "Layer", result)
3070 << tcu::TestLog::EndImageSet;
3071
3072 return tcu::TestStatus::fail("Failed");
3073 }
3074
3075 }
3076
3077 // SampleMaskWithDepthTestInstance
3078 #ifndef CTS_USES_VULKANSC
SampleMaskWithDepthTestInstance(Context & context,const PipelineConstructionType pipelineConstructionType,const VkSampleCountFlagBits rasterizationSamples,const bool enablePostDepthCoverage,const bool useFragmentShadingRate)3079 SampleMaskWithDepthTestInstance::SampleMaskWithDepthTestInstance (Context& context,
3080 const PipelineConstructionType pipelineConstructionType,
3081 const VkSampleCountFlagBits rasterizationSamples,
3082 const bool enablePostDepthCoverage,
3083 const bool useFragmentShadingRate)
3084 : vkt::TestInstance (context)
3085 , m_pipelineConstructionType(pipelineConstructionType)
3086 , m_rasterizationSamples (rasterizationSamples)
3087 , m_enablePostDepthCoverage (enablePostDepthCoverage)
3088 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
3089 , m_depthStencilFormat (VK_FORMAT_D16_UNORM)
3090 , m_renderSize (tcu::IVec2(3, 3))
3091 , m_useDepth (true)
3092 , m_useStencil (false)
3093 , m_topology (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
3094 , m_renderColor (tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f))
3095 , m_vertices (generateVertices())
3096 , m_multisampleStateParams (getMultisampleState(rasterizationSamples))
3097 , m_blendState (getDefaultColorBlendAttachmentState())
3098 , m_renderType (RENDER_TYPE_RESOLVE)
3099 , m_imageBackingMode (IMAGE_BACKING_MODE_REGULAR)
3100 , m_depthClearValue (0.667f)
3101 , m_useFragmentShadingRate (useFragmentShadingRate)
3102 {
3103 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_2_BIT] = SampleCoverage(1u, 1u); // !< Sample coverage of the diagonally halved pixel,
3104 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_4_BIT] = SampleCoverage(2u, 2u); // !< with max possible subPixelPrecisionBits threshold
3105 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_8_BIT] = SampleCoverage(2u, 6u); // !<
3106 m_refCoverageAfterDepthTest[VK_SAMPLE_COUNT_16_BIT] = SampleCoverage(6u, 11u); // !<
3107 }
3108
iterate(void)3109 tcu::TestStatus SampleMaskWithDepthTestInstance::iterate (void)
3110 {
3111 de::MovePtr<tcu::TextureLevel> result;
3112
3113 MultisampleRenderer renderer (m_context, m_pipelineConstructionType, m_colorFormat, m_depthStencilFormat, m_renderSize, m_useDepth, m_useStencil, 1u, &m_topology,
3114 &m_vertices, m_multisampleStateParams, m_blendState, m_renderType, m_imageBackingMode, m_useFragmentShadingRate, m_depthClearValue);
3115 result = renderer.render();
3116
3117 return verifyImage(result->getAccess());
3118 }
3119
getMultisampleState(const VkSampleCountFlagBits rasterizationSamples)3120 VkPipelineMultisampleStateCreateInfo SampleMaskWithDepthTestInstance::getMultisampleState (const VkSampleCountFlagBits rasterizationSamples)
3121 {
3122 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
3123 {
3124 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
3125 DE_NULL, // const void* pNext;
3126 0u, // VkPipelineMultisampleStateCreateFlags flags;
3127 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
3128 false, // VkBool32 sampleShadingEnable;
3129 0.0f, // float minSampleShading;
3130 DE_NULL, // const VkSampleMask* pSampleMask;
3131 false, // VkBool32 alphaToCoverageEnable;
3132 false // VkBool32 alphaToOneEnable;
3133 };
3134
3135 return multisampleStateParams;
3136 }
3137
generateVertices(void)3138 std::vector<Vertex4RGBA> SampleMaskWithDepthTestInstance::generateVertices (void)
3139 {
3140 std::vector<Vertex4RGBA> vertices;
3141
3142 {
3143 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f), m_renderColor };
3144 vertices.push_back(vertexInput);
3145 }
3146 {
3147 const Vertex4RGBA vertexInput = { tcu::Vec4(1.0f, -1.0f, 1.0f, 1.0f), m_renderColor };
3148 vertices.push_back(vertexInput);
3149 }
3150 {
3151 const Vertex4RGBA vertexInput = { tcu::Vec4(-1.0f, 1.0f, 1.0f, 1.0f), m_renderColor };
3152 vertices.push_back(vertexInput);
3153 }
3154
3155 return vertices;
3156 }
3157
verifyImage(const tcu::ConstPixelBufferAccess & result)3158 tcu::TestStatus SampleMaskWithDepthTestInstance::verifyImage (const tcu::ConstPixelBufferAccess& result)
3159 {
3160 bool pass = true;
3161 const int width = result.getWidth();
3162 const int height = result.getHeight();
3163 tcu::TestLog& log = m_context.getTestContext().getLog();
3164
3165 DE_ASSERT(width == 3);
3166 DE_ASSERT(height == 3);
3167
3168 const tcu::Vec4 clearColor = tcu::Vec4(0.0f);
3169
3170 for (int x = 0; x < width; ++x)
3171 for (int y = 0; y < height; ++y)
3172 {
3173 const tcu::Vec4 resultPixel = result.getPixel(x, y);
3174
3175 if (x + y == 0)
3176 {
3177 const float threshold = 0.02f;
3178 tcu::Vec4 expectedPixel = m_renderColor;
3179
3180 if (m_useFragmentShadingRate && m_enablePostDepthCoverage)
3181 {
3182 // The fragment shader for this test outputs a fragment value that
3183 // is based off gl_SampleMaskIn. For the FSR case that sample mask
3184 // applies to 4 pixels, rather than the usual 1 pixel per fragment
3185 // shader invocation. Those 4 pixels represent:
3186 // a) The fully covered pixel (this "x + y == 0" case)
3187 // b) The two partially covered pixels (the "x + y == 1" case below)
3188 // c) The non-covered pixel (the "else" case below)
3189 //
3190 // For the PostDepthCoverage case, the gl_SampleMaskIn represents
3191 // coverage after the depth test, so it has roughly 50% of the bits
3192 // set. This means that the expected result for this case (a)
3193 // will not be the "m_renderColor" but ~50% of the m_renderColor.
3194 expectedPixel = expectedPixel * tcu::Vec4(0.5f);
3195 }
3196
3197 bool localPass = true;
3198 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3199 {
3200 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= expectedPixel[componentNdx] * (1.0f - threshold)
3201 || resultPixel[componentNdx] >= expectedPixel[componentNdx] * (1.0f + threshold)))
3202 localPass = false;
3203 }
3204
3205 if (!localPass)
3206 {
3207 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3208 << " Reference range ( " << expectedPixel * (1.0f - threshold) << " ; " << expectedPixel * (1.0f + threshold) << " )" << tcu::TestLog::EndMessage;
3209 pass = false;
3210 }
3211 }
3212 else if (x + y == 1)
3213 {
3214 const float threshold = 0.02f;
3215 float minCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].min / (float)m_rasterizationSamples;
3216 float maxCoverage = (float)m_refCoverageAfterDepthTest[m_rasterizationSamples].max / (float)m_rasterizationSamples;
3217
3218 // default: m_rasterizationSamples bits set in FS's gl_SampleMaskIn[0] (before depth test)
3219 // post_depth_coverage: m_refCoverageAfterDepthTest[m_rasterizationSamples] bits set in FS's gl_SampleMaskIn[0] (after depth test)
3220
3221 if (m_enablePostDepthCoverage)
3222 {
3223 minCoverage *= minCoverage;
3224 maxCoverage *= maxCoverage;
3225 }
3226
3227 bool localPass = true;
3228 for (deUint32 componentNdx = 0u; componentNdx < m_renderColor.SIZE; ++componentNdx)
3229 {
3230 if (m_renderColor[componentNdx] != 0.0f && (resultPixel[componentNdx] <= m_renderColor[componentNdx] * (minCoverage - threshold)
3231 || resultPixel[componentNdx] >= m_renderColor[componentNdx] * (maxCoverage + threshold)))
3232 localPass = false;
3233 }
3234
3235 if (!localPass)
3236 {
3237 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3238 << " Reference range ( " << m_renderColor * (minCoverage - threshold) << " ; " << m_renderColor * (maxCoverage + threshold) << " )" << tcu::TestLog::EndMessage;
3239 pass = false;
3240 }
3241 }
3242 else
3243 {
3244 if (resultPixel != clearColor)
3245 {
3246 log << tcu::TestLog::Message << "x: " << x << " y: " << y << " Result: " << resultPixel
3247 << " Reference: " << clearColor << tcu::TestLog::EndMessage;
3248 pass = false;
3249 }
3250 }
3251 }
3252
3253 if (pass)
3254 return tcu::TestStatus::pass("Passed");
3255 else
3256 return tcu::TestStatus::fail("Failed");
3257 }
3258 #endif // CTS_USES_VULKANSC
3259 // MultisampleRenderer
3260
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)3261 MultisampleRenderer::MultisampleRenderer (Context& context,
3262 const PipelineConstructionType pipelineConstructionType,
3263 const VkFormat colorFormat,
3264 const tcu::IVec2& renderSize,
3265 const VkPrimitiveTopology topology,
3266 const std::vector<Vertex4RGBA>& vertices,
3267 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
3268 const VkPipelineColorBlendAttachmentState& blendState,
3269 const RenderType renderType,
3270 const ImageBackingMode backingMode,
3271 const bool useFragmentShadingRate)
3272 : m_context (context)
3273 , m_pipelineConstructionType(pipelineConstructionType)
3274 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3275 , m_colorFormat (colorFormat)
3276 , m_depthStencilFormat (VK_FORMAT_UNDEFINED)
3277 , m_renderSize (renderSize)
3278 , m_useDepth (false)
3279 , m_useStencil (false)
3280 , m_useConservative (false)
3281 , m_multisampleStateParams (multisampleStateParams)
3282 , m_colorBlendState (blendState)
3283 , m_rasterizationConservativeStateCreateInfo ()
3284 , m_renderType (renderType)
3285 , m_backingMode (backingMode)
3286 , m_depthClearValue (1.0f)
3287 , m_useFragmentShadingRate (useFragmentShadingRate)
3288 {
3289 initialize(context, 1u, &topology, &vertices);
3290 }
3291
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)3292 MultisampleRenderer::MultisampleRenderer (Context& context,
3293 const PipelineConstructionType pipelineConstructionType,
3294 const VkFormat colorFormat,
3295 const VkFormat depthStencilFormat,
3296 const tcu::IVec2& renderSize,
3297 const bool useDepth,
3298 const bool useStencil,
3299 const deUint32 numTopologies,
3300 const VkPrimitiveTopology* pTopology,
3301 const std::vector<Vertex4RGBA>* pVertices,
3302 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
3303 const VkPipelineColorBlendAttachmentState& blendState,
3304 const RenderType renderType,
3305 const ImageBackingMode backingMode,
3306 const bool useFragmentShadingRate,
3307 const float depthClearValue)
3308 : m_context (context)
3309 , m_pipelineConstructionType(pipelineConstructionType)
3310 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3311 , m_colorFormat (colorFormat)
3312 , m_depthStencilFormat (depthStencilFormat)
3313 , m_renderSize (renderSize)
3314 , m_useDepth (useDepth)
3315 , m_useStencil (useStencil)
3316 , m_useConservative (false)
3317 , m_multisampleStateParams (multisampleStateParams)
3318 , m_colorBlendState (blendState)
3319 , m_rasterizationConservativeStateCreateInfo ()
3320 , m_renderType (renderType)
3321 , m_backingMode (backingMode)
3322 , m_depthClearValue (depthClearValue)
3323 , m_useFragmentShadingRate (useFragmentShadingRate)
3324 {
3325 initialize(context, numTopologies, pTopology, pVertices);
3326 }
3327
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)3328 MultisampleRenderer::MultisampleRenderer (Context& context,
3329 const PipelineConstructionType pipelineConstructionType,
3330 const VkFormat colorFormat,
3331 const VkFormat depthStencilFormat,
3332 const tcu::IVec2& renderSize,
3333 const bool useDepth,
3334 const bool useStencil,
3335 const bool useConservative,
3336 const bool useFragmentShadingRate,
3337 const deUint32 numTopologies,
3338 const VkPrimitiveTopology* pTopology,
3339 const std::vector<Vertex4RGBA>* pVertices,
3340 const VkPipelineMultisampleStateCreateInfo& multisampleStateParams,
3341 const VkPipelineColorBlendAttachmentState& blendState,
3342 const VkPipelineRasterizationConservativeStateCreateInfoEXT& conservativeStateCreateInfo,
3343 const RenderType renderType,
3344 const ImageBackingMode backingMode,
3345 const float depthClearValue)
3346 : m_context (context)
3347 , m_pipelineConstructionType(pipelineConstructionType)
3348 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
3349 , m_colorFormat (colorFormat)
3350 , m_depthStencilFormat (depthStencilFormat)
3351 , m_renderSize (renderSize)
3352 , m_useDepth (useDepth)
3353 , m_useStencil (useStencil)
3354 , m_useConservative (useConservative)
3355 , m_multisampleStateParams (multisampleStateParams)
3356 , m_colorBlendState (blendState)
3357 , m_rasterizationConservativeStateCreateInfo (conservativeStateCreateInfo)
3358 , m_renderType (renderType)
3359 , m_backingMode (backingMode)
3360 , m_depthClearValue (depthClearValue)
3361 , m_useFragmentShadingRate (useFragmentShadingRate)
3362 {
3363 initialize(context, numTopologies, pTopology, pVertices);
3364 }
3365
initialize(Context & context,const deUint32 numTopologies,const VkPrimitiveTopology * pTopology,const std::vector<Vertex4RGBA> * pVertices)3366 void MultisampleRenderer::initialize (Context& context,
3367 const deUint32 numTopologies,
3368 const VkPrimitiveTopology* pTopology,
3369 const std::vector<Vertex4RGBA>* pVertices)
3370 {
3371 if (!isSupportedSampleCount(context.getInstanceInterface(), context.getPhysicalDevice(), m_multisampleStateParams.rasterizationSamples))
3372 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
3373
3374 const DeviceInterface& vk = context.getDeviceInterface();
3375 const VkDevice vkDevice = context.getDevice();
3376 const VkPhysicalDeviceFeatures features = context.getDeviceFeatures();
3377 const deUint32 queueFamilyIndices[] = { context.getUniversalQueueFamilyIndex(), context.getSparseQueueFamilyIndex() };
3378 const bool sparse = m_backingMode == IMAGE_BACKING_MODE_SPARSE;
3379 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
3380 const VkImageCreateFlags imageCreateFlags = sparse ? (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) : 0u;
3381 const VkSharingMode sharingMode = (sparse && context.getUniversalQueueFamilyIndex() != context.getSparseQueueFamilyIndex()) ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
3382 Allocator& memAlloc = m_context.getDefaultAllocator();
3383 const bool usesResolveImage = m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT;
3384
3385 if (sparse)
3386 {
3387 bool sparseSamplesSupported = false;
3388 switch(m_multisampleStateParams.rasterizationSamples)
3389 {
3390 case VK_SAMPLE_COUNT_1_BIT:
3391 sparseSamplesSupported = features.sparseResidencyImage2D;
3392 break;
3393 case VK_SAMPLE_COUNT_2_BIT:
3394 sparseSamplesSupported = features.sparseResidency2Samples;
3395 break;
3396 case VK_SAMPLE_COUNT_4_BIT:
3397 sparseSamplesSupported = features.sparseResidency4Samples;
3398 break;
3399 case VK_SAMPLE_COUNT_8_BIT:
3400 sparseSamplesSupported = features.sparseResidency8Samples;
3401 break;
3402 case VK_SAMPLE_COUNT_16_BIT:
3403 sparseSamplesSupported = features.sparseResidency16Samples;
3404 break;
3405 default:
3406 break;
3407 }
3408
3409 if (!sparseSamplesSupported)
3410 throw tcu::NotSupportedError("Unsupported number of rasterization samples for sparse residency");
3411 }
3412
3413 if (sparse && !context.getDeviceFeatures().sparseBinding)
3414 throw tcu::NotSupportedError("No sparseBinding support");
3415
3416 // Create color image
3417 {
3418 const VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3419 (m_renderType == RENDER_TYPE_COPY_SAMPLES ? VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0u);
3420
3421 const VkImageCreateInfo colorImageParams =
3422 {
3423 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3424 DE_NULL, // const void* pNext;
3425 imageCreateFlags, // VkImageCreateFlags flags;
3426 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3427 m_colorFormat, // VkFormat format;
3428 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
3429 1u, // deUint32 mipLevels;
3430 1u, // deUint32 arrayLayers;
3431 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
3432 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3433 imageUsageFlags, // VkImageUsageFlags usage;
3434 sharingMode, // VkSharingMode sharingMode;
3435 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u, // deUint32 queueFamilyIndexCount;
3436 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
3437 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3438 };
3439
3440 #ifndef CTS_USES_VULKANSC
3441 if (sparse && !checkSparseImageFormatSupport(context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams))
3442 TCU_THROW(NotSupportedError, "The image format does not support sparse operations.");
3443 #endif // CTS_USES_VULKANSC
3444
3445 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
3446
3447 // Allocate and bind color image memory
3448 if (sparse)
3449 {
3450 #ifndef CTS_USES_VULKANSC
3451 allocateAndBindSparseImage(vk, vkDevice, context.getPhysicalDevice(), context.getInstanceInterface(), colorImageParams, *m_bindSemaphore, context.getSparseQueue(), memAlloc, m_allocations, mapVkFormat(m_colorFormat), *m_colorImage);
3452 #endif // CTS_USES_VULKANSC
3453 }
3454 else
3455 {
3456 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
3457 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
3458 }
3459 }
3460
3461 // Create resolve image
3462 if (usesResolveImage)
3463 {
3464 const VkImageCreateInfo resolveImageParams =
3465 {
3466 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3467 DE_NULL, // const void* pNext;
3468 0u, // VkImageCreateFlags flags;
3469 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3470 m_colorFormat, // VkFormat format;
3471 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
3472 1u, // deUint32 mipLevels;
3473 1u, // deUint32 arrayLayers;
3474 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3475 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3476 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage;
3477 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3478 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3479 1u, // deUint32 queueFamilyIndexCount;
3480 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
3481 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3482 };
3483
3484 m_resolveImage = createImage(vk, vkDevice, &resolveImageParams);
3485
3486 // Allocate and bind resolve image memory
3487 m_resolveImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_resolveImage), MemoryRequirement::Any);
3488 VK_CHECK(vk.bindImageMemory(vkDevice, *m_resolveImage, m_resolveImageAlloc->getMemory(), m_resolveImageAlloc->getOffset()));
3489
3490 // Create resolve attachment view
3491 {
3492 const VkImageViewCreateInfo resolveAttachmentViewParams =
3493 {
3494 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3495 DE_NULL, // const void* pNext;
3496 0u, // VkImageViewCreateFlags flags;
3497 *m_resolveImage, // VkImage image;
3498 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3499 m_colorFormat, // VkFormat format;
3500 componentMappingRGBA, // VkComponentMapping components;
3501 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
3502 };
3503
3504 m_resolveAttachmentView = createImageView(vk, vkDevice, &resolveAttachmentViewParams);
3505 }
3506 }
3507
3508 // Create per-sample output images
3509 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3510 {
3511 const VkImageCreateInfo perSampleImageParams =
3512 {
3513 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3514 DE_NULL, // const void* pNext;
3515 0u, // VkImageCreateFlags flags;
3516 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3517 m_colorFormat, // VkFormat format;
3518 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
3519 1u, // deUint32 mipLevels;
3520 1u, // deUint32 arrayLayers;
3521 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3522 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3523 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | // VkImageUsageFlags usage;
3524 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
3525 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3526 1u, // deUint32 queueFamilyIndexCount;
3527 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
3528 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3529 };
3530
3531 m_perSampleImages.resize(static_cast<size_t>(m_multisampleStateParams.rasterizationSamples));
3532
3533 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3534 {
3535 m_perSampleImages[i] = de::SharedPtr<PerSampleImage>(new PerSampleImage);
3536 PerSampleImage& image = *m_perSampleImages[i];
3537
3538 image.m_image = createImage(vk, vkDevice, &perSampleImageParams);
3539
3540 // Allocate and bind image memory
3541 image.m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *image.m_image), MemoryRequirement::Any);
3542 VK_CHECK(vk.bindImageMemory(vkDevice, *image.m_image, image.m_imageAlloc->getMemory(), image.m_imageAlloc->getOffset()));
3543
3544 // Create per-sample attachment view
3545 {
3546 const VkImageViewCreateInfo perSampleAttachmentViewParams =
3547 {
3548 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3549 DE_NULL, // const void* pNext;
3550 0u, // VkImageViewCreateFlags flags;
3551 *image.m_image, // VkImage image;
3552 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3553 m_colorFormat, // VkFormat format;
3554 componentMappingRGBA, // VkComponentMapping components;
3555 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
3556 };
3557
3558 image.m_attachmentView = createImageView(vk, vkDevice, &perSampleAttachmentViewParams);
3559 }
3560 }
3561 }
3562
3563 // Create a depth/stencil image
3564 if (m_useDepth || m_useStencil)
3565 {
3566 const VkImageCreateInfo depthStencilImageParams =
3567 {
3568 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3569 DE_NULL, // const void* pNext;
3570 0u, // VkImageCreateFlags flags;
3571 VK_IMAGE_TYPE_2D, // VkImageType imageType;
3572 m_depthStencilFormat, // VkFormat format;
3573 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
3574 1u, // deUint32 mipLevels;
3575 1u, // deUint32 arrayLayers;
3576 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
3577 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
3578 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, // VkImageUsageFlags usage;
3579 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3580 1u, // deUint32 queueFamilyIndexCount;
3581 queueFamilyIndices, // const deUint32* pQueueFamilyIndices;
3582 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
3583 };
3584
3585 m_depthStencilImage = createImage(vk, vkDevice, &depthStencilImageParams);
3586
3587 // Allocate and bind depth/stencil image memory
3588 m_depthStencilImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthStencilImage), MemoryRequirement::Any);
3589 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthStencilImage, m_depthStencilImageAlloc->getMemory(), m_depthStencilImageAlloc->getOffset()));
3590 }
3591
3592 // Create color attachment view
3593 {
3594 const VkImageViewCreateInfo colorAttachmentViewParams =
3595 {
3596 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3597 DE_NULL, // const void* pNext;
3598 0u, // VkImageViewCreateFlags flags;
3599 *m_colorImage, // VkImage image;
3600 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3601 m_colorFormat, // VkFormat format;
3602 componentMappingRGBA, // VkComponentMapping components;
3603 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
3604 };
3605
3606 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
3607 }
3608
3609 VkImageAspectFlags depthStencilAttachmentAspect = (VkImageAspectFlagBits)0;
3610
3611 // Create depth/stencil attachment view
3612 if (m_useDepth || m_useStencil)
3613 {
3614 depthStencilAttachmentAspect = getImageAspectFlags(m_depthStencilFormat);
3615
3616 const VkImageViewCreateInfo depthStencilAttachmentViewParams =
3617 {
3618 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
3619 DE_NULL, // const void* pNext;
3620 0u, // VkImageViewCreateFlags flags;
3621 *m_depthStencilImage, // VkImage image;
3622 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
3623 m_depthStencilFormat, // VkFormat format;
3624 componentMappingRGBA, // VkComponentMapping components;
3625 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
3626 };
3627
3628 m_depthStencilAttachmentView = createImageView(vk, vkDevice, &depthStencilAttachmentViewParams);
3629 }
3630
3631 // Create render pass
3632 {
3633 std::vector<VkAttachmentDescription> attachmentDescriptions;
3634 {
3635 const VkAttachmentDescription colorAttachmentDescription =
3636 {
3637 0u, // VkAttachmentDescriptionFlags flags;
3638 m_colorFormat, // VkFormat format;
3639 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
3640 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3641 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3642 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3643 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3644 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3645 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
3646 };
3647 attachmentDescriptions.push_back(colorAttachmentDescription);
3648 }
3649
3650 deUint32 resolveAttachmentIndex = VK_ATTACHMENT_UNUSED;
3651
3652 if (usesResolveImage)
3653 {
3654 resolveAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3655
3656 const VkAttachmentDescription resolveAttachmentDescription =
3657 {
3658 0u, // VkAttachmentDescriptionFlags flags;
3659 m_colorFormat, // VkFormat format;
3660 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3661 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3662 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3663 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3664 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3665 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3666 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
3667 };
3668 attachmentDescriptions.push_back(resolveAttachmentDescription);
3669 }
3670
3671 deUint32 perSampleAttachmentIndex = VK_ATTACHMENT_UNUSED;
3672
3673 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3674 {
3675 perSampleAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3676
3677 const VkAttachmentDescription perSampleAttachmentDescription =
3678 {
3679 0u, // VkAttachmentDescriptionFlags flags;
3680 m_colorFormat, // VkFormat format;
3681 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
3682 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
3683 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
3684 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
3685 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
3686 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3687 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
3688 };
3689
3690 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3691 {
3692 attachmentDescriptions.push_back(perSampleAttachmentDescription);
3693 }
3694 }
3695
3696 deUint32 depthStencilAttachmentIndex = VK_ATTACHMENT_UNUSED;
3697
3698 if (m_useDepth || m_useStencil)
3699 {
3700 depthStencilAttachmentIndex = static_cast<deUint32>(attachmentDescriptions.size());
3701
3702 const VkAttachmentDescription depthStencilAttachmentDescription =
3703 {
3704 0u, // VkAttachmentDescriptionFlags flags;
3705 m_depthStencilFormat, // VkFormat format;
3706 m_multisampleStateParams.rasterizationSamples, // VkSampleCountFlagBits samples;
3707 (m_useDepth ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentLoadOp loadOp;
3708 (m_useDepth ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp storeOp;
3709 (m_useStencil ? VK_ATTACHMENT_LOAD_OP_CLEAR : VK_ATTACHMENT_LOAD_OP_DONT_CARE), // VkAttachmentStoreOp stencilLoadOp;
3710 (m_useStencil ? VK_ATTACHMENT_STORE_OP_STORE : VK_ATTACHMENT_STORE_OP_DONT_CARE), // VkAttachmentStoreOp stencilStoreOp;
3711 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
3712 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
3713 };
3714 attachmentDescriptions.push_back(depthStencilAttachmentDescription);
3715 }
3716
3717 const VkAttachmentReference colorAttachmentReference =
3718 {
3719 0u, // deUint32 attachment;
3720 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3721 };
3722
3723 const VkAttachmentReference inputAttachmentReference =
3724 {
3725 0u, // deUint32 attachment;
3726 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout layout;
3727 };
3728
3729 const VkAttachmentReference resolveAttachmentReference =
3730 {
3731 resolveAttachmentIndex, // deUint32 attachment;
3732 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3733 };
3734
3735 const VkAttachmentReference colorAttachmentReferencesUnusedAttachment[] =
3736 {
3737 {
3738 VK_ATTACHMENT_UNUSED, // deUint32 attachment
3739 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout
3740 },
3741 {
3742 0u, // deUint32 attachment
3743 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
3744 }
3745 };
3746
3747 const VkAttachmentReference resolveAttachmentReferencesUnusedAttachment[] =
3748 {
3749 {
3750 VK_ATTACHMENT_UNUSED, // deUint32 attachment
3751 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout
3752 },
3753 {
3754 resolveAttachmentIndex, // deUint32 attachment
3755 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
3756 }
3757 };
3758
3759 std::vector<VkAttachmentReference> perSampleAttachmentReferences(m_perSampleImages.size());
3760 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3761 {
3762 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3763 {
3764 const VkAttachmentReference perSampleAttachmentReference =
3765 {
3766 perSampleAttachmentIndex + static_cast<deUint32>(i), // deUint32 attachment;
3767 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3768 };
3769 perSampleAttachmentReferences[i] = perSampleAttachmentReference;
3770 }
3771 }
3772
3773 const VkAttachmentReference depthStencilAttachmentReference =
3774 {
3775 depthStencilAttachmentIndex, // deUint32 attachment;
3776 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout layout;
3777 };
3778
3779 std::vector<VkSubpassDescription> subpassDescriptions;
3780 std::vector<VkSubpassDependency> subpassDependencies;
3781
3782 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
3783 {
3784 const VkSubpassDescription subpassDescription0 =
3785 {
3786 0u, // VkSubpassDescriptionFlags flags
3787 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
3788 0u, // deUint32 inputAttachmentCount
3789 DE_NULL, // const VkAttachmentReference* pInputAttachments
3790 0u, // deUint32 colorAttachmentCount
3791 DE_NULL, // const VkAttachmentReference* pColorAttachments
3792 DE_NULL, // const VkAttachmentReference* pResolveAttachments
3793 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
3794 0u, // deUint32 preserveAttachmentCount
3795 DE_NULL // const VkAttachmentReference* pPreserveAttachments
3796 };
3797
3798 const VkSubpassDescription subpassDescription1 =
3799 {
3800 0u, // VkSubpassDescriptionFlags flags
3801 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
3802 0u, // deUint32 inputAttachmentCount
3803 DE_NULL, // const VkAttachmentReference* pInputAttachments
3804 1u, // deUint32 colorAttachmentCount
3805 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments
3806 &resolveAttachmentReference, // const VkAttachmentReference* pResolveAttachments
3807 &depthStencilAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment
3808 0u, // deUint32 preserveAttachmentCount
3809 DE_NULL // const VkAttachmentReference* pPreserveAttachments
3810 };
3811
3812 const VkSubpassDependency subpassDependency =
3813 {
3814 0u, // deUint32 srcSubpass
3815 1u, // deUint32 dstSubpass
3816 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags srcStageMask
3817 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, // VkPipelineStageFlags dstStageMask
3818 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3819 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
3820 0u // VkDependencyFlags dependencyFlags
3821 };
3822
3823 subpassDescriptions.push_back(subpassDescription0);
3824 subpassDescriptions.push_back(subpassDescription1);
3825 subpassDependencies.push_back(subpassDependency);
3826 }
3827 else if (m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
3828 {
3829 const VkSubpassDescription renderSubpassDescription =
3830 {
3831 0u, // VkSubpassDescriptionFlags flags
3832 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
3833 0u, // deUint32 inputAttachmentCount
3834 DE_NULL, // const VkAttachmentReference* pInputAttachments
3835 2u, // deUint32 colorAttachmentCount
3836 colorAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pColorAttachments
3837 resolveAttachmentReferencesUnusedAttachment, // const VkAttachmentReference* pResolveAttachments
3838 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
3839 0u, // deUint32 preserveAttachmentCount
3840 DE_NULL // const VkAttachmentReference* pPreserveAttachments
3841 };
3842
3843 subpassDescriptions.push_back(renderSubpassDescription);
3844 }
3845 else
3846 {
3847 {
3848 const VkSubpassDescription renderSubpassDescription =
3849 {
3850 0u, // VkSubpassDescriptionFlags flags;
3851 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3852 0u, // deUint32 inputAttachmentCount;
3853 DE_NULL, // const VkAttachmentReference* pInputAttachments;
3854 1u, // deUint32 colorAttachmentCount;
3855 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
3856 usesResolveImage ? &resolveAttachmentReference : DE_NULL, // const VkAttachmentReference* pResolveAttachments;
3857 (m_useDepth || m_useStencil ? &depthStencilAttachmentReference : DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment;
3858 0u, // deUint32 preserveAttachmentCount;
3859 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
3860 };
3861 subpassDescriptions.push_back(renderSubpassDescription);
3862 }
3863
3864 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3865 {
3866
3867 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3868 {
3869 const VkSubpassDescription copySampleSubpassDescription =
3870 {
3871 0u, // VkSubpassDescriptionFlags flags;
3872 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
3873 1u, // deUint32 inputAttachmentCount;
3874 &inputAttachmentReference, // const VkAttachmentReference* pInputAttachments;
3875 1u, // deUint32 colorAttachmentCount;
3876 &perSampleAttachmentReferences[i], // const VkAttachmentReference* pColorAttachments;
3877 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
3878 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
3879 0u, // deUint32 preserveAttachmentCount;
3880 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
3881 };
3882 subpassDescriptions.push_back(copySampleSubpassDescription);
3883
3884 const VkSubpassDependency copySampleSubpassDependency =
3885 {
3886 0u, // deUint32 srcSubpass
3887 1u + static_cast<deUint32>(i), // deUint32 dstSubpass
3888 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
3889 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
3890 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3891 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
3892 0u, // VkDependencyFlags dependencyFlags
3893 };
3894 subpassDependencies.push_back(copySampleSubpassDependency);
3895 }
3896 // the very last sample pass must synchronize with all prior subpasses
3897 for (size_t i = 0; i < (m_perSampleImages.size() - 1); ++i)
3898 {
3899 const VkSubpassDependency storeSubpassDependency =
3900 {
3901 1u + static_cast<deUint32>(i), // deUint32 srcSubpass
3902 static_cast<deUint32>(m_perSampleImages.size()), // deUint32 dstSubpass
3903 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
3904 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
3905 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
3906 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
3907 0u, // VkDependencyFlags dependencyFlags
3908 };
3909 subpassDependencies.push_back(storeSubpassDependency);
3910 }
3911 }
3912 }
3913
3914 const VkRenderPassCreateInfo renderPassParams =
3915 {
3916 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
3917 DE_NULL, // const void* pNext;
3918 0u, // VkRenderPassCreateFlags flags;
3919 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
3920 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
3921 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount;
3922 &subpassDescriptions[0], // const VkSubpassDescription* pSubpasses;
3923 (deUint32)subpassDependencies.size(), // deUint32 dependencyCount;
3924 subpassDependencies.size() != 0 ? &subpassDependencies[0] : DE_NULL
3925 };
3926
3927 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
3928 }
3929
3930 // Create framebuffer
3931 {
3932 std::vector<VkImageView> attachments;
3933 attachments.push_back(*m_colorAttachmentView);
3934 if (usesResolveImage)
3935 {
3936 attachments.push_back(*m_resolveAttachmentView);
3937 }
3938 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3939 {
3940 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
3941 {
3942 attachments.push_back(*m_perSampleImages[i]->m_attachmentView);
3943 }
3944 }
3945
3946 if (m_useDepth || m_useStencil)
3947 {
3948 attachments.push_back(*m_depthStencilAttachmentView);
3949 }
3950
3951 const VkFramebufferCreateInfo framebufferParams =
3952 {
3953 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
3954 DE_NULL, // const void* pNext;
3955 0u, // VkFramebufferCreateFlags flags;
3956 *m_renderPass, // VkRenderPass renderPass;
3957 (deUint32)attachments.size(), // deUint32 attachmentCount;
3958 &attachments[0], // const VkImageView* pAttachments;
3959 (deUint32)m_renderSize.x(), // deUint32 width;
3960 (deUint32)m_renderSize.y(), // deUint32 height;
3961 1u // deUint32 layers;
3962 };
3963
3964 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
3965 }
3966
3967 // Create pipeline layout
3968 {
3969 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
3970 {
3971 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
3972 DE_NULL, // const void* pNext;
3973 0u, // VkPipelineLayoutCreateFlags flags;
3974 0u, // deUint32 setLayoutCount;
3975 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
3976 0u, // deUint32 pushConstantRangeCount;
3977 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
3978 };
3979
3980 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
3981
3982 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
3983 {
3984
3985 // Create descriptor set layout
3986 const VkDescriptorSetLayoutBinding layoutBinding =
3987 {
3988 0u, // deUint32 binding;
3989 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
3990 1u, // deUint32 descriptorCount;
3991 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
3992 DE_NULL, // const VkSampler* pImmutableSamplers;
3993 };
3994
3995 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
3996 {
3997 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
3998 DE_NULL, // const void* pNext
3999 0u, // VkDescriptorSetLayoutCreateFlags flags
4000 1u, // deUint32 bindingCount
4001 &layoutBinding // const VkDescriptorSetLayoutBinding* pBindings
4002 };
4003 m_copySampleDesciptorLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
4004
4005 // Create pipeline layout
4006
4007 const VkPushConstantRange pushConstantRange =
4008 {
4009 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
4010 0u, // deUint32 offset;
4011 sizeof(deInt32) // deUint32 size;
4012 };
4013 const VkPipelineLayoutCreateInfo copySamplePipelineLayoutParams =
4014 {
4015 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
4016 DE_NULL, // const void* pNext;
4017 0u, // VkPipelineLayoutCreateFlags flags;
4018 1u, // deUint32 setLayoutCount;
4019 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
4020 1u, // deUint32 pushConstantRangeCount;
4021 &pushConstantRange // const VkPushConstantRange* pPushConstantRanges;
4022 };
4023 m_copySamplePipelineLayout = createPipelineLayout(vk, vkDevice, ©SamplePipelineLayoutParams);
4024 }
4025 }
4026
4027 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
4028 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
4029
4030 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4031 {
4032 m_copySampleVertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("quad_vert"), 0);
4033 m_copySampleFragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("copy_sample_frag"), 0);
4034 }
4035
4036 // Create pipeline
4037 {
4038 const VkVertexInputBindingDescription vertexInputBindingDescription =
4039 {
4040 0u, // deUint32 binding;
4041 sizeof(Vertex4RGBA), // deUint32 stride;
4042 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
4043 };
4044
4045 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
4046 {
4047 {
4048 0u, // deUint32 location;
4049 0u, // deUint32 binding;
4050 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4051 0u // deUint32 offset;
4052 },
4053 {
4054 1u, // deUint32 location;
4055 0u, // deUint32 binding;
4056 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
4057 DE_OFFSET_OF(Vertex4RGBA, color), // deUint32 offset;
4058 }
4059 };
4060
4061 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
4062 {
4063 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
4064 DE_NULL, // const void* pNext;
4065 0u, // VkPipelineVertexInputStateCreateFlags flags;
4066 1u, // deUint32 vertexBindingDescriptionCount;
4067 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
4068 2u, // deUint32 vertexAttributeDescriptionCount;
4069 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
4070 };
4071
4072 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) };
4073 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) };
4074
4075 const deUint32 attachmentCount = m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT ? 2u : 1u;
4076
4077 std::vector<VkPipelineColorBlendAttachmentState> attachments;
4078
4079 for (deUint32 attachmentIdx = 0; attachmentIdx < attachmentCount; attachmentIdx++)
4080 attachments.push_back(m_colorBlendState);
4081
4082 VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
4083 {
4084 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4085 DE_NULL, // const void* pNext;
4086 0u, // VkPipelineColorBlendStateCreateFlags flags;
4087 false, // VkBool32 logicOpEnable;
4088 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
4089 attachmentCount, // deUint32 attachmentCount;
4090 attachments.data(), // const VkPipelineColorBlendAttachmentState* pAttachments;
4091 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
4092 };
4093
4094 const VkStencilOpState stencilOpState =
4095 {
4096 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
4097 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp;
4098 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
4099 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp;
4100 1u, // deUint32 compareMask;
4101 1u, // deUint32 writeMask;
4102 1u, // deUint32 reference;
4103 };
4104
4105 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
4106 {
4107 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
4108 DE_NULL, // const void* pNext;
4109 0u, // VkPipelineDepthStencilStateCreateFlags flags;
4110 m_useDepth, // VkBool32 depthTestEnable;
4111 m_useDepth, // VkBool32 depthWriteEnable;
4112 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
4113 false, // VkBool32 depthBoundsTestEnable;
4114 m_useStencil, // VkBool32 stencilTestEnable;
4115 stencilOpState, // VkStencilOpState front;
4116 stencilOpState, // VkStencilOpState back;
4117 0.0f, // float minDepthBounds;
4118 1.0f, // float maxDepthBounds;
4119 };
4120
4121 const VkPipelineRasterizationStateCreateInfo rasterizationStateCreateInfo
4122 {
4123 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
4124 m_useConservative ? &m_rasterizationConservativeStateCreateInfo : DE_NULL, // const void* pNext
4125 0u, // VkPipelineRasterizationStateCreateFlags flags
4126 VK_FALSE, // VkBool32 depthClampEnable
4127 VK_FALSE, // VkBool32 rasterizerDiscardEnable
4128 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
4129 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
4130 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
4131 VK_FALSE, // VkBool32 depthBiasEnable
4132 0.0f, // float depthBiasConstantFactor
4133 0.0f, // float depthBiasClamp
4134 0.0f, // float depthBiasSlopeFactor
4135 1.0f // float lineWidth
4136 };
4137
4138 VkPipelineFragmentShadingRateStateCreateInfoKHR shadingRateStateCreateInfo
4139 {
4140 VK_STRUCTURE_TYPE_PIPELINE_FRAGMENT_SHADING_RATE_STATE_CREATE_INFO_KHR, // VkStructureType sType;
4141 DE_NULL, // const void* pNext;
4142 { 2, 2 }, // VkExtent2D fragmentSize;
4143 { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR }, // VkFragmentShadingRateCombinerOpKHR combinerOps[2];
4144 };
4145
4146 const deUint32 numSubpasses = m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY ? 2u : 1u;
4147
4148 m_graphicsPipelines.reserve(numSubpasses * numTopologies);
4149 for (deUint32 subpassIdx = 0; subpassIdx < numSubpasses; subpassIdx++)
4150 {
4151 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4152 {
4153 if (subpassIdx == 0)
4154 {
4155 colorBlendStateParams.attachmentCount = 0;
4156 }
4157 else
4158 {
4159 colorBlendStateParams.attachmentCount = 1;
4160 }
4161 }
4162 for (deUint32 i = 0u; i < numTopologies; ++i)
4163 {
4164 m_graphicsPipelines.emplace_back(vk, vkDevice, m_pipelineConstructionType);
4165 m_graphicsPipelines.back().setDefaultTopology(pTopology[i])
4166 .setupVertexInputState(&vertexInputStateParams)
4167 .setupPreRasterizationShaderState(viewports,
4168 scissors,
4169 *m_pipelineLayout,
4170 *m_renderPass,
4171 subpassIdx,
4172 *m_vertexShaderModule,
4173 &rasterizationStateCreateInfo,
4174 DE_NULL, DE_NULL, DE_NULL, DE_NULL,
4175 (m_useFragmentShadingRate ? &shadingRateStateCreateInfo : nullptr))
4176 .setupFragmentShaderState(*m_pipelineLayout,
4177 *m_renderPass,
4178 subpassIdx,
4179 *m_fragmentShaderModule,
4180 &depthStencilStateParams,
4181 &m_multisampleStateParams)
4182 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &m_multisampleStateParams)
4183 .setMonolithicPipelineLayout(*m_pipelineLayout)
4184 .buildPipeline();
4185 }
4186 }
4187 }
4188
4189 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4190 {
4191 // Create pipelines for copying samples to single sampled images
4192 {
4193 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams
4194 {
4195 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
4196 DE_NULL, // const void* pNext;
4197 0u, // VkPipelineVertexInputStateCreateFlags flags;
4198 0u, // deUint32 vertexBindingDescriptionCount;
4199 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
4200 0u, // deUint32 vertexAttributeDescriptionCount;
4201 DE_NULL // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
4202 };
4203
4204 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) };
4205 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) };
4206
4207 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams
4208 {
4209 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4210 DE_NULL, // const void* pNext;
4211 0u, // VkPipelineColorBlendStateCreateFlags flags;
4212 false, // VkBool32 logicOpEnable;
4213 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
4214 1u, // deUint32 attachmentCount;
4215 &m_colorBlendState, // const VkPipelineColorBlendAttachmentState* pAttachments;
4216 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
4217 };
4218
4219 m_copySamplePipelines.reserve(m_perSampleImages.size());
4220 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4221 {
4222 // Pipeline is to be used in subpasses subsequent to sample-shading subpass
4223
4224 const deUint32 subpassIdx = 1u + (deUint32)i;
4225 m_copySamplePipelines.emplace_back(vk, vkDevice, m_pipelineConstructionType);
4226 m_copySamplePipelines.back().setDefaultTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP)
4227 .setDefaultRasterizationState()
4228 .setDefaultMultisampleState()
4229 .setDefaultDepthStencilState()
4230 .setupVertexInputState(&vertexInputStateParams)
4231 .setupPreRasterizationShaderState(viewports,
4232 scissors,
4233 *m_copySamplePipelineLayout,
4234 *m_renderPass,
4235 subpassIdx,
4236 *m_copySampleVertexShaderModule)
4237 .setupFragmentShaderState(*m_copySamplePipelineLayout,
4238 *m_renderPass,
4239 subpassIdx,
4240 *m_copySampleFragmentShaderModule)
4241 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams)
4242 .setMonolithicPipelineLayout(*m_copySamplePipelineLayout)
4243 .buildPipeline();
4244 }
4245 }
4246
4247 const VkDescriptorPoolSize descriptorPoolSize
4248 {
4249 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type;
4250 1u // deUint32 descriptorCount;
4251 };
4252
4253 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo
4254 {
4255 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
4256 DE_NULL, // const void* pNext
4257 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
4258 1u, // deUint32 maxSets
4259 1u, // deUint32 poolSizeCount
4260 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes
4261 };
4262
4263 m_copySampleDesciptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
4264
4265 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo
4266 {
4267 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
4268 DE_NULL, // const void* pNext
4269 *m_copySampleDesciptorPool, // VkDescriptorPool descriptorPool
4270 1u, // deUint32 descriptorSetCount
4271 &m_copySampleDesciptorLayout.get(), // const VkDescriptorSetLayout* pSetLayouts
4272 };
4273
4274 m_copySampleDesciptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
4275
4276 const VkDescriptorImageInfo imageInfo
4277 {
4278 DE_NULL,
4279 *m_colorAttachmentView,
4280 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
4281 };
4282 const VkWriteDescriptorSet descriptorWrite
4283 {
4284 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType;
4285 DE_NULL, // const void* pNext;
4286 *m_copySampleDesciptorSet, // VkDescriptorSet dstSet;
4287 0u, // deUint32 dstBinding;
4288 0u, // deUint32 dstArrayElement;
4289 1u, // deUint32 descriptorCount;
4290 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType;
4291 &imageInfo, // const VkDescriptorImageInfo* pImageInfo;
4292 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo;
4293 DE_NULL, // const VkBufferView* pTexelBufferView;
4294 };
4295 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
4296 }
4297
4298 // Create vertex buffer
4299 {
4300 const VkBufferCreateInfo vertexBufferParams
4301 {
4302 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
4303 DE_NULL, // const void* pNext;
4304 0u, // VkBufferCreateFlags flags;
4305 1024u, // VkDeviceSize size;
4306 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
4307 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4308 1u, // deUint32 queueFamilyIndexCount;
4309 &queueFamilyIndices[0] // const deUint32* pQueueFamilyIndices;
4310 };
4311
4312 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
4313 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
4314
4315 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
4316
4317 // Load vertices into vertex buffer
4318 {
4319 Vertex4RGBA* pDst = static_cast<Vertex4RGBA*>(m_vertexBufferAlloc->getHostPtr());
4320
4321 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4322 {
4323 DE_ASSERT(numTopologies == 1);
4324
4325 std::vector<Vertex4RGBA> vertices = pVertices[0];
4326
4327 // Set alpha to zero for the first draw. This should prevent depth writes because of zero coverage.
4328 for (size_t i = 0; i < vertices.size(); i++)
4329 vertices[i].color.w() = 0.0f;
4330
4331 deMemcpy(pDst, &vertices[0], vertices.size() * sizeof(Vertex4RGBA));
4332
4333 pDst += vertices.size();
4334
4335 // The second draw uses original vertices which are pure red.
4336 deMemcpy(pDst, &pVertices[0][0], pVertices[0].size() * sizeof(Vertex4RGBA));
4337 }
4338 else
4339 {
4340 for (deUint32 i = 0u; i < numTopologies; ++i)
4341 {
4342 deMemcpy(pDst, &pVertices[i][0], pVertices[i].size() * sizeof(Vertex4RGBA));
4343 pDst += pVertices[i].size();
4344 }
4345 }
4346 }
4347 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
4348 }
4349
4350 // Create command pool
4351 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndices[0]);
4352
4353 // Create command buffer
4354 {
4355 VkClearValue colorClearValue;
4356 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4357 {
4358 colorClearValue.color.float32[0] = 0.25;
4359 colorClearValue.color.float32[1] = 0.25;
4360 colorClearValue.color.float32[2] = 0.25;
4361 colorClearValue.color.float32[3] = 1.0f;
4362 }
4363 else
4364 {
4365 colorClearValue.color.float32[0] = 0.0f;
4366 colorClearValue.color.float32[1] = 0.0f;
4367 colorClearValue.color.float32[2] = 0.0f;
4368 colorClearValue.color.float32[3] = 0.0f;
4369 }
4370
4371 VkClearValue depthStencilClearValue;
4372 depthStencilClearValue.depthStencil.depth = m_depthClearValue;
4373 depthStencilClearValue.depthStencil.stencil = 0u;
4374
4375 std::vector<VkClearValue> clearValues;
4376 clearValues.push_back(colorClearValue);
4377 if (usesResolveImage)
4378 {
4379 clearValues.push_back(colorClearValue);
4380 }
4381 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4382 {
4383 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4384 {
4385 clearValues.push_back(colorClearValue);
4386 }
4387 }
4388 if (m_useDepth || m_useStencil)
4389 {
4390 clearValues.push_back(depthStencilClearValue);
4391 }
4392
4393 vk::VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
4394 std::vector<VkImageMemoryBarrier> imageLayoutBarriers;
4395
4396 {
4397 const VkImageMemoryBarrier colorImageBarrier =
4398 // color attachment image
4399 {
4400 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4401 DE_NULL, // const void* pNext;
4402 0u, // VkAccessFlags srcAccessMask;
4403 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
4404 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4405 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
4406 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4407 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4408 *m_colorImage, // VkImage image;
4409 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
4410 };
4411 imageLayoutBarriers.push_back(colorImageBarrier);
4412 }
4413 if (usesResolveImage)
4414 {
4415 const VkImageMemoryBarrier resolveImageBarrier =
4416 // resolve attachment image
4417 {
4418 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4419 DE_NULL, // const void* pNext;
4420 0u, // VkAccessFlags srcAccessMask;
4421 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
4422 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4423 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
4424 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4425 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4426 *m_resolveImage, // VkImage image;
4427 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
4428 };
4429 imageLayoutBarriers.push_back(resolveImageBarrier);
4430 }
4431 if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4432 {
4433 for (size_t i = 0; i < m_perSampleImages.size(); ++i)
4434 {
4435 const VkImageMemoryBarrier perSampleImageBarrier =
4436 // resolve attachment image
4437 {
4438 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4439 DE_NULL, // const void* pNext;
4440 0u, // VkAccessFlags srcAccessMask;
4441 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
4442 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4443 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
4444 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4445 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4446 *m_perSampleImages[i]->m_image, // VkImage image;
4447 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
4448 };
4449 imageLayoutBarriers.push_back(perSampleImageBarrier);
4450 }
4451 }
4452 if (m_useDepth || m_useStencil)
4453 {
4454 const VkImageMemoryBarrier depthStencilImageBarrier =
4455 // depth/stencil attachment image
4456 {
4457 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4458 DE_NULL, // const void* pNext;
4459 0u, // VkAccessFlags srcAccessMask;
4460 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
4461 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4462 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
4463 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4464 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4465 *m_depthStencilImage, // VkImage image;
4466 { depthStencilAttachmentAspect, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange;
4467 };
4468 imageLayoutBarriers.push_back(depthStencilImageBarrier);
4469 dstStageMask |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
4470 }
4471
4472 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
4473
4474 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
4475
4476 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, dstStageMask, (VkDependencyFlags)0,
4477 0u, DE_NULL, 0u, DE_NULL, (deUint32)imageLayoutBarriers.size(), &imageLayoutBarriers[0]);
4478
4479 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)clearValues.size(), &clearValues[0]);
4480
4481 VkDeviceSize vertexBufferOffset = 0u;
4482
4483 for (deUint32 i = 0u; i < numTopologies; ++i)
4484 {
4485 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipelines[i].getPipeline());
4486 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4487 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[i].size(), 1, 0, 0);
4488
4489 vertexBufferOffset += static_cast<VkDeviceSize>(pVertices[i].size() * sizeof(Vertex4RGBA));
4490 }
4491
4492 if (m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY)
4493 {
4494 // The first draw was without color buffer and zero coverage. The depth buffer is expected to still have the clear value.
4495 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
4496 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipelines[1].getPipeline());
4497 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
4498 // The depth test should pass as the first draw didn't touch the depth buffer.
4499 vk.cmdDraw(*m_cmdBuffer, (deUint32)pVertices[0].size(), 1, 0, 0);
4500 }
4501 else if (m_renderType == RENDER_TYPE_COPY_SAMPLES)
4502 {
4503 // Copy each sample id to single sampled image
4504 for (deInt32 sampleId = 0; sampleId < (deInt32)m_perSampleImages.size(); ++sampleId)
4505 {
4506 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
4507 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_copySamplePipelines[sampleId].getPipeline());
4508 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_copySamplePipelineLayout, 0u, 1u, &m_copySampleDesciptorSet.get(), 0u, DE_NULL);
4509 vk.cmdPushConstants(*m_cmdBuffer, *m_copySamplePipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(deInt32), &sampleId);
4510 vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
4511 }
4512 }
4513
4514 endRenderPass(vk, *m_cmdBuffer);
4515
4516 endCommandBuffer(vk, *m_cmdBuffer);
4517 }
4518 }
4519
~MultisampleRenderer(void)4520 MultisampleRenderer::~MultisampleRenderer (void)
4521 {
4522 }
4523
render(void)4524 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::render (void)
4525 {
4526 const DeviceInterface& vk = m_context.getDeviceInterface();
4527 const VkDevice vkDevice = m_context.getDevice();
4528 const VkQueue queue = m_context.getUniversalQueue();
4529 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
4530
4531 if (m_backingMode == IMAGE_BACKING_MODE_SPARSE)
4532 {
4533 const VkPipelineStageFlags stageBits[] = { VK_PIPELINE_STAGE_TRANSFER_BIT };
4534 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get(), false, 1u, 1u, &m_bindSemaphore.get(), stageBits);
4535 }
4536 else
4537 {
4538 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
4539 }
4540
4541 if (m_renderType == RENDER_TYPE_RESOLVE || m_renderType == RENDER_TYPE_DEPTHSTENCIL_ONLY || m_renderType == RENDER_TYPE_UNUSED_ATTACHMENT)
4542 {
4543 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_resolveImage, m_colorFormat, m_renderSize.cast<deUint32>());
4544 }
4545 else if(m_renderType == RENDER_TYPE_SINGLE_SAMPLE)
4546 {
4547 return readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, m_context.getDefaultAllocator(), *m_colorImage, m_colorFormat, m_renderSize.cast<deUint32>());
4548 }
4549 else
4550 {
4551 return de::MovePtr<tcu::TextureLevel>();
4552 }
4553 }
4554
getSingleSampledImage(deUint32 sampleId)4555 de::MovePtr<tcu::TextureLevel> MultisampleRenderer::getSingleSampledImage (deUint32 sampleId)
4556 {
4557 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>());
4558 }
4559
4560 // Multisample tests with subpasses using no attachments.
4561 class VariableRateTestCase : public vkt::TestCase
4562 {
4563 public:
4564 using SampleCounts = std::vector<vk::VkSampleCountFlagBits>;
4565
4566 struct PushConstants
4567 {
4568 int width;
4569 int height;
4570 int samples;
4571 };
4572
4573 struct TestParams
4574 {
4575 PipelineConstructionType pipelineConstructionType; // The way pipeline is constructed.
4576 bool nonEmptyFramebuffer; // Empty framebuffer or not.
4577 vk::VkSampleCountFlagBits fbCount; // If not empty, framebuffer sample count.
4578 bool unusedAttachment; // If not empty, create unused attachment or not.
4579 SampleCounts subpassCounts; // Counts for the different subpasses.
4580 bool useFragmentShadingRate; // Use pipeline fragment shading rate.
4581 };
4582
4583 static const deInt32 kWidth = 256u;
4584 static const deInt32 kHeight = 256u;
4585
4586 VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params);
~VariableRateTestCase(void)4587 virtual ~VariableRateTestCase (void) {}
4588
4589 virtual void initPrograms (vk::SourceCollections& programCollection) const;
4590 virtual TestInstance* createInstance (Context& context) const;
4591 virtual void checkSupport (Context& context) const;
4592
4593 static constexpr vk::VkFormat kColorFormat = vk::VK_FORMAT_R8G8B8A8_UNORM;
4594
4595 private:
4596 TestParams m_params;
4597 };
4598
4599 class VariableRateTestInstance : public vkt::TestInstance
4600 {
4601 public:
4602 using TestParams = VariableRateTestCase::TestParams;
4603
4604 VariableRateTestInstance (Context& context, const TestParams& counts);
~VariableRateTestInstance(void)4605 virtual ~VariableRateTestInstance (void) {}
4606
4607 virtual tcu::TestStatus iterate (void);
4608
4609 private:
4610 TestParams m_params;
4611 };
4612
VariableRateTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams & params)4613 VariableRateTestCase::VariableRateTestCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, const TestParams& params)
4614 : vkt::TestCase (testCtx, name, description)
4615 , m_params (params)
4616 {
4617 }
4618
initPrograms(vk::SourceCollections & programCollection) const4619 void VariableRateTestCase::initPrograms (vk::SourceCollections& programCollection) const
4620 {
4621 std::stringstream vertSrc;
4622
4623 vertSrc << "#version 450\n"
4624 << "\n"
4625 << "layout(location=0) in vec2 inPos;\n"
4626 << "\n"
4627 << "void main() {\n"
4628 << " gl_Position = vec4(inPos, 0.0, 1.0);\n"
4629 << "}\n"
4630 ;
4631
4632 std::stringstream fragSrc;
4633
4634 fragSrc << "#version 450\n"
4635 << "\n"
4636 << "layout(set=0, binding=0, std430) buffer OutBuffer {\n"
4637 << " int coverage[];\n"
4638 << "} out_buffer;\n"
4639 << "\n"
4640 << "layout(push_constant) uniform PushConstants {\n"
4641 << " int width;\n"
4642 << " int height;\n"
4643 << " int samples;\n"
4644 << "} push_constants;\n"
4645 << "\n"
4646 << "void main() {\n"
4647 << " ivec2 coord = ivec2(floor(gl_FragCoord.xy));\n"
4648 << " int pos = ((coord.y * push_constants.width) + coord.x) * push_constants.samples + int(gl_SampleID);\n"
4649 << " out_buffer.coverage[pos] = 1;\n"
4650 << "}\n"
4651 ;
4652
4653 programCollection.glslSources.add("vert") << glu::VertexSource(vertSrc.str());
4654 programCollection.glslSources.add("frag") << glu::FragmentSource(fragSrc.str());
4655 }
4656
createInstance(Context & context) const4657 TestInstance* VariableRateTestCase::createInstance (Context& context) const
4658 {
4659 return new VariableRateTestInstance(context, m_params);
4660 }
4661
checkSupport(Context & context) const4662 void VariableRateTestCase::checkSupport (Context& context) const
4663 {
4664 const auto& vki = context.getInstanceInterface();
4665 const auto physicalDevice = context.getPhysicalDevice();
4666
4667 // When using multiple subpasses, require variableMultisampleRate.
4668 if (m_params.subpassCounts.size() > 1)
4669 {
4670 if (!vk::getPhysicalDeviceFeatures(vki, physicalDevice).variableMultisampleRate)
4671 TCU_THROW(NotSupportedError, "Variable multisample rate not supported");
4672 }
4673
4674 // Check if sampleRateShading is supported.
4675 if(!vk::getPhysicalDeviceFeatures(vki, physicalDevice).sampleRateShading)
4676 TCU_THROW(NotSupportedError, "Sample rate shading is not supported");
4677
4678 // Make sure all subpass sample counts are supported.
4679 const auto properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
4680 const auto& supportedCounts = properties.limits.framebufferNoAttachmentsSampleCounts;
4681
4682 for (const auto count : m_params.subpassCounts)
4683 {
4684 if ((supportedCounts & count) == 0u)
4685 TCU_THROW(NotSupportedError, "Sample count combination not supported");
4686 }
4687
4688 if (m_params.nonEmptyFramebuffer)
4689 {
4690 // Check the framebuffer sample count is supported.
4691 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);
4692 if ((formatProperties.sampleCounts & m_params.fbCount) == 0u)
4693 TCU_THROW(NotSupportedError, "Sample count of " + de::toString(m_params.fbCount) + " not supported for color attachment");
4694 }
4695
4696 if (m_params.useFragmentShadingRate && !checkFragmentShadingRateRequirements(context, m_params.fbCount))
4697 TCU_THROW(NotSupportedError, "Required FragmentShadingRate not supported");
4698
4699 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_params.pipelineConstructionType);
4700 }
4701
zeroOutAndFlush(const vk::DeviceInterface & vkd,vk::VkDevice device,vk::BufferWithMemory & buffer,vk::VkDeviceSize size)4702 void zeroOutAndFlush(const vk::DeviceInterface& vkd, vk::VkDevice device, vk::BufferWithMemory& buffer, vk::VkDeviceSize size)
4703 {
4704 auto& alloc = buffer.getAllocation();
4705 deMemset(alloc.getHostPtr(), 0, static_cast<size_t>(size));
4706 vk::flushAlloc(vkd, device, alloc);
4707 }
4708
VariableRateTestInstance(Context & context,const TestParams & params)4709 VariableRateTestInstance::VariableRateTestInstance (Context& context, const TestParams& params)
4710 : vkt::TestInstance (context)
4711 , m_params (params)
4712 {
4713 }
4714
iterate(void)4715 tcu::TestStatus VariableRateTestInstance::iterate (void)
4716 {
4717 using PushConstants = VariableRateTestCase::PushConstants;
4718
4719 const auto& vkd = m_context.getDeviceInterface();
4720 const auto device = m_context.getDevice();
4721 auto& allocator = m_context.getDefaultAllocator();
4722 const auto& queue = m_context.getUniversalQueue();
4723 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
4724
4725 const vk::VkDeviceSize kWidth = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kWidth);
4726 const vk::VkDeviceSize kHeight = static_cast<vk::VkDeviceSize>(VariableRateTestCase::kHeight);
4727 constexpr auto kColorFormat = VariableRateTestCase::kColorFormat;
4728
4729 const auto kWidth32 = static_cast<deUint32>(kWidth);
4730 const auto kHeight32 = static_cast<deUint32>(kHeight);
4731
4732 std::vector<std::unique_ptr<vk::BufferWithMemory>> referenceBuffers;
4733 std::vector<std::unique_ptr<vk::BufferWithMemory>> outputBuffers;
4734 std::vector<size_t> bufferNumElements;
4735 std::vector<vk::VkDeviceSize> bufferSizes;
4736
4737 // Create reference and output buffers.
4738 for (const auto count : m_params.subpassCounts)
4739 {
4740 bufferNumElements.push_back(static_cast<size_t>(kWidth * kHeight * count));
4741 bufferSizes.push_back(bufferNumElements.back() * sizeof(deInt32));
4742 const auto bufferCreateInfo = vk::makeBufferCreateInfo(bufferSizes.back(), vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
4743
4744 referenceBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
4745 outputBuffers.emplace_back (new vk::BufferWithMemory{vkd, device, allocator, bufferCreateInfo, MemoryRequirement::HostVisible});
4746 }
4747
4748 // Descriptor set layout.
4749 vk::DescriptorSetLayoutBuilder builder;
4750 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_FRAGMENT_BIT);
4751 const auto descriptorSetLayout = builder.build(vkd, device);
4752
4753 // Pipeline layout.
4754 const vk::VkPushConstantRange pushConstantRange =
4755 {
4756 vk::VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
4757 0u, // deUint32 offset;
4758 static_cast<deUint32>(sizeof(PushConstants)), // deUint32 size;
4759 };
4760
4761 const vk::VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo =
4762 {
4763 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
4764 nullptr, // const void* pNext;
4765 0u, // VkPipelineLayoutCreateFlags flags;
4766 1u, // deUint32 setLayoutCount;
4767 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
4768 1u, // deUint32 pushConstantRangeCount;
4769 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
4770 };
4771 const auto pipelineLayout = vk::createPipelineLayout(vkd, device, &pipelineLayoutCreateInfo);
4772
4773 // Subpass with no attachments.
4774 const vk::VkSubpassDescription emptySubpassDescription =
4775 {
4776 0u, // VkSubpassDescriptionFlags flags;
4777 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
4778 0u, // deUint32 inputAttachmentCount;
4779 nullptr, // const VkAttachmentReference* pInputAttachments;
4780 0u, // deUint32 colorAttachmentCount;
4781 nullptr, // const VkAttachmentReference* pColorAttachments;
4782 nullptr, // const VkAttachmentReference* pResolveAttachments;
4783 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
4784 0u, // deUint32 preserveAttachmentCount;
4785 nullptr, // const deUint32* pPreserveAttachments;
4786 };
4787
4788 // Unused attachment reference.
4789 const vk::VkAttachmentReference unusedAttachmentReference =
4790 {
4791 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
4792 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout;
4793 };
4794
4795 // Subpass with unused attachment.
4796 const vk::VkSubpassDescription unusedAttachmentSubpassDescription =
4797 {
4798 0u, // VkSubpassDescriptionFlags flags;
4799 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
4800 0u, // deUint32 inputAttachmentCount;
4801 nullptr, // const VkAttachmentReference* pInputAttachments;
4802 1u, // deUint32 colorAttachmentCount;
4803 &unusedAttachmentReference, // const VkAttachmentReference* pColorAttachments;
4804 nullptr, // const VkAttachmentReference* pResolveAttachments;
4805 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
4806 0u, // deUint32 preserveAttachmentCount;
4807 nullptr, // const deUint32* pPreserveAttachments;
4808 };
4809
4810 // Renderpass with multiple subpasses.
4811 vk::VkRenderPassCreateInfo renderPassCreateInfo =
4812 {
4813 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
4814 nullptr, // const void* pNext;
4815 0u, // VkRenderPassCreateFlags flags;
4816 0u, // deUint32 attachmentCount;
4817 nullptr, // const VkAttachmentDescription* pAttachments;
4818 0u, // deUint32 subpassCount;
4819 nullptr, // const VkSubpassDescription* pSubpasses;
4820 0u, // deUint32 dependencyCount;
4821 nullptr, // const VkSubpassDependency* pDependencies;
4822 };
4823
4824 std::vector<vk::VkSubpassDescription> subpassesVector;
4825
4826 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
4827 subpassesVector.push_back(emptySubpassDescription);
4828 renderPassCreateInfo.subpassCount = static_cast<deUint32>(subpassesVector.size());
4829 renderPassCreateInfo.pSubpasses = subpassesVector.data();
4830 const auto renderPassMultiplePasses = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
4831
4832 // Render pass with single subpass.
4833 const vk::VkAttachmentDescription colorAttachmentDescription =
4834 {
4835 0u, // VkAttachmentDescriptionFlags flags;
4836 kColorFormat, // VkFormat format;
4837 m_params.fbCount, // VkSampleCountFlagBits samples;
4838 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
4839 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
4840 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
4841 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
4842 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4843 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout finalLayout;
4844 };
4845
4846 if (m_params.nonEmptyFramebuffer)
4847 {
4848 renderPassCreateInfo.attachmentCount = 1u;
4849 renderPassCreateInfo.pAttachments = &colorAttachmentDescription;
4850 }
4851 const bool unusedAttachmentSubpass = (m_params.nonEmptyFramebuffer && m_params.unusedAttachment);
4852 renderPassCreateInfo.subpassCount = 1u;
4853 renderPassCreateInfo.pSubpasses = (unusedAttachmentSubpass ? &unusedAttachmentSubpassDescription : &emptySubpassDescription);
4854 const auto renderPassSingleSubpass = vk::createRenderPass(vkd, device, &renderPassCreateInfo);
4855
4856 // Framebuffers.
4857 vk::VkFramebufferCreateInfo framebufferCreateInfo =
4858 {
4859 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
4860 nullptr, // const void* pNext;
4861 0u, // VkFramebufferCreateFlags flags;
4862 DE_NULL, // VkRenderPass renderPass;
4863 0u, // deUint32 attachmentCount;
4864 nullptr, // const VkImageView* pAttachments;
4865 kWidth32, // deUint32 width;
4866 kHeight32, // deUint32 height;
4867 1u, // deUint32 layers;
4868 };
4869
4870 // Framebuffer for multiple-subpasses render pass.
4871 framebufferCreateInfo.renderPass = renderPassMultiplePasses.get();
4872 const auto framebufferMultiplePasses = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
4873
4874 // Framebuffer for single-subpass render pass.
4875 std::unique_ptr<vk::ImageWithMemory> imagePtr;
4876 vk::Move<vk::VkImageView> imageView;
4877
4878 if (m_params.nonEmptyFramebuffer)
4879 {
4880 const vk::VkImageCreateInfo imageCreateInfo =
4881 {
4882 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4883 nullptr, // const void* pNext;
4884 0u, // VkImageCreateFlags flags;
4885 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType;
4886 kColorFormat, // VkFormat format;
4887 vk::makeExtent3D(kWidth32, kHeight32, 1u), // VkExtent3D extent;
4888 1u, // deUint32 mipLevels;
4889 1u, // deUint32 arrayLayers;
4890 m_params.fbCount, // VkSampleCountFlagBits samples;
4891 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4892 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, // VkImageUsageFlags usage;
4893 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4894 0u, // deUint32 queueFamilyIndexCount;
4895 nullptr, // const deUint32* pQueueFamilyIndices;
4896 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4897 };
4898 imagePtr.reset(new vk::ImageWithMemory{vkd, device, allocator, imageCreateInfo, MemoryRequirement::Any});
4899
4900 const auto subresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
4901 imageView = vk::makeImageView(vkd, device, imagePtr->get(), vk::VK_IMAGE_VIEW_TYPE_2D, kColorFormat, subresourceRange);
4902
4903 framebufferCreateInfo.attachmentCount = 1u;
4904 framebufferCreateInfo.pAttachments = &imageView.get();
4905 }
4906 framebufferCreateInfo.renderPass = renderPassSingleSubpass.get();
4907 const auto framebufferSingleSubpass = vk::createFramebuffer(vkd, device, &framebufferCreateInfo);
4908
4909 // Shader modules and stages.
4910 const auto vertModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
4911 const auto fragModule = vk::createShaderModule(vkd, device, m_context.getBinaryCollection().get("frag"), 0u);
4912
4913 // Vertices, input state and assembly.
4914 const std::vector<tcu::Vec2> vertices =
4915 {
4916 { -0.987f, -0.964f },
4917 { 0.982f, -0.977f },
4918 { 0.005f, 0.891f },
4919 };
4920
4921 const auto vertexBinding = vk::makeVertexInputBindingDescription(0u, static_cast<deUint32>(sizeof(decltype(vertices)::value_type)), vk::VK_VERTEX_INPUT_RATE_VERTEX);
4922 const auto vertexAttribute = vk::makeVertexInputAttributeDescription(0u, 0u, vk::VK_FORMAT_R32G32_SFLOAT, 0u);
4923
4924 const vk::VkPipelineVertexInputStateCreateInfo vertexInputStateCreateInfo =
4925 {
4926 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
4927 nullptr, // const void* pNext;
4928 0u, // VkPipelineVertexInputStateCreateFlags flags;
4929 1u, // deUint32 vertexBindingDescriptionCount;
4930 &vertexBinding, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
4931 1u, // deUint32 vertexAttributeDescriptionCount;
4932 &vertexAttribute, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
4933 };
4934
4935 // Graphics pipelines to create output buffers.
4936 const std::vector<VkViewport> viewport { vk::makeViewport(kWidth32, kHeight32) };
4937 const std::vector<VkRect2D> scissor { vk::makeRect2D(kWidth32, kHeight32) };
4938
4939 const VkColorComponentFlags colorComponentFlags = (VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
4940
4941 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
4942 {
4943 VK_FALSE, // VkBool32 blendEnable;
4944 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor;
4945 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
4946 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
4947 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor;
4948 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
4949 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
4950 colorComponentFlags, // VkColorComponentFlags colorWriteMask;
4951 };
4952
4953 const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoNoAttachments =
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 0u, // deUint32 attachmentCount;
4961 nullptr, // const VkPipelineColorBlendAttachmentState* pAttachments;
4962 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
4963 };
4964
4965 const vk::VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoOneAttachment =
4966 {
4967 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
4968 DE_NULL, // const void* pNext;
4969 0u, // VkPipelineColorBlendStateCreateFlags flags;
4970 VK_FALSE, // VkBool32 logicOpEnable;
4971 vk::VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp;
4972 1u, // deUint32 attachmentCount;
4973 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
4974 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
4975 };
4976
4977 vk::VkPipelineMultisampleStateCreateInfo multisampleStateCreateInfo
4978 {
4979 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
4980 nullptr, // const void* pNext;
4981 0u, // VkPipelineMultisampleStateCreateFlags flags;
4982 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
4983 VK_FALSE, // VkBool32 sampleShadingEnable;
4984 0.0f, // float minSampleShading;
4985 nullptr, // const VkSampleMask* pSampleMask;
4986 VK_FALSE, // VkBool32 alphaToCoverageEnable;
4987 VK_FALSE, // VkBool32 alphaToOneEnable;
4988 };
4989
4990 std::vector<GraphicsPipelineWrapper> outputPipelines;
4991 outputPipelines.reserve(m_params.subpassCounts.size());
4992 for (const auto samples : m_params.subpassCounts)
4993 {
4994 const auto colorBlendStatePtr = (unusedAttachmentSubpass ? &colorBlendStateCreateInfoOneAttachment : &colorBlendStateCreateInfoNoAttachments);
4995
4996 multisampleStateCreateInfo.rasterizationSamples = samples;
4997
4998 outputPipelines.emplace_back(vkd, device, m_params.pipelineConstructionType);
4999 outputPipelines.back()
5000 .setDefaultDepthStencilState()
5001 .setDefaultRasterizationState()
5002 .setupVertexInputState(&vertexInputStateCreateInfo)
5003 .setupPreRasterizationShaderState(viewport,
5004 scissor,
5005 *pipelineLayout,
5006 *renderPassSingleSubpass,
5007 0u,
5008 *vertModule)
5009 .setupFragmentShaderState(*pipelineLayout, *renderPassSingleSubpass, 0u, *fragModule, DE_NULL, &multisampleStateCreateInfo)
5010 .setupFragmentOutputState(*renderPassSingleSubpass, 0u, colorBlendStatePtr, &multisampleStateCreateInfo)
5011 .setMonolithicPipelineLayout(*pipelineLayout)
5012 .buildPipeline();
5013 }
5014
5015 // Graphics pipelines with variable rate but using several subpasses.
5016 std::vector<GraphicsPipelineWrapper> referencePipelines;
5017 referencePipelines.reserve(m_params.subpassCounts.size());
5018 for (size_t i = 0; i < m_params.subpassCounts.size(); ++i)
5019 {
5020 multisampleStateCreateInfo.rasterizationSamples = m_params.subpassCounts[i];
5021
5022 deUint32 subpass = static_cast<deUint32>(i);
5023 referencePipelines.emplace_back(vkd, device, m_params.pipelineConstructionType);
5024 referencePipelines.back()
5025 .setDefaultDepthStencilState()
5026 .setDefaultRasterizationState()
5027 .setupVertexInputState(&vertexInputStateCreateInfo)
5028 .setupPreRasterizationShaderState(viewport,
5029 scissor,
5030 *pipelineLayout,
5031 *renderPassMultiplePasses,
5032 subpass,
5033 *vertModule)
5034 .setupFragmentShaderState(*pipelineLayout, *renderPassMultiplePasses, subpass, *fragModule, DE_NULL, &multisampleStateCreateInfo)
5035 .setupFragmentOutputState(*renderPassMultiplePasses, subpass, &colorBlendStateCreateInfoNoAttachments, &multisampleStateCreateInfo)
5036 .setMonolithicPipelineLayout(*pipelineLayout)
5037 .buildPipeline();
5038 }
5039
5040 // Prepare vertex, reference and output buffers.
5041 const auto vertexBufferSize = vertices.size() * sizeof(decltype(vertices)::value_type);
5042 const auto vertexBufferCreateInfo = vk::makeBufferCreateInfo(static_cast<VkDeviceSize>(vertexBufferSize), vk::VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
5043 vk::BufferWithMemory vertexBuffer {vkd, device, allocator, vertexBufferCreateInfo, MemoryRequirement::HostVisible};
5044 auto& vertexAlloc = vertexBuffer.getAllocation();
5045
5046 deMemcpy(vertexAlloc.getHostPtr(), vertices.data(), vertexBufferSize);
5047 vk::flushAlloc(vkd, device, vertexAlloc);
5048
5049 for (size_t i = 0; i < referenceBuffers.size(); ++i)
5050 {
5051 zeroOutAndFlush(vkd, device, *referenceBuffers[i], bufferSizes[i]);
5052 zeroOutAndFlush(vkd, device, *outputBuffers[i], bufferSizes[i]);
5053 }
5054
5055 // Prepare descriptor sets.
5056 const deUint32 totalSets = static_cast<deUint32>(referenceBuffers.size() * 2u);
5057 vk::DescriptorPoolBuilder poolBuilder;
5058 poolBuilder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, static_cast<deUint32>(referenceBuffers.size() * 2u));
5059 const auto descriptorPool = poolBuilder.build(vkd, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, totalSets);
5060
5061 std::vector<vk::Move<vk::VkDescriptorSet>> referenceSets (referenceBuffers.size());
5062 std::vector<vk::Move<vk::VkDescriptorSet>> outputSets (outputBuffers.size());
5063
5064 for (auto& set : referenceSets)
5065 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
5066 for (auto& set : outputSets)
5067 set = vk::makeDescriptorSet(vkd, device, descriptorPool.get(), descriptorSetLayout.get());
5068
5069 vk::DescriptorSetUpdateBuilder updateBuilder;
5070
5071 for (size_t i = 0; i < referenceSets.size(); ++i)
5072 {
5073 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(referenceBuffers[i]->get(), 0u, bufferSizes[i]);
5074 updateBuilder.writeSingle(referenceSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
5075 }
5076 for (size_t i = 0; i < outputSets.size(); ++i)
5077 {
5078 const auto descriptorBufferInfo = vk::makeDescriptorBufferInfo(outputBuffers[i]->get(), 0u, bufferSizes[i]);
5079 updateBuilder.writeSingle(outputSets[i].get(), vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorBufferInfo);
5080 }
5081
5082 updateBuilder.update(vkd, device);
5083
5084 // Prepare command pool.
5085 const auto cmdPool = vk::makeCommandPool(vkd, device, queueIndex);
5086 const auto cmdBufferPtr = vk::allocateCommandBuffer(vkd , device, cmdPool.get(), vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY);
5087 const auto cmdBuffer = cmdBufferPtr.get();
5088
5089 vk::VkBufferMemoryBarrier storageBufferDevToHostBarrier =
5090 {
5091 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
5092 nullptr, // const void* pNext;
5093 vk::VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask;
5094 vk::VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
5095 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5096 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5097 DE_NULL, // VkBuffer buffer;
5098 0u, // VkDeviceSize offset;
5099 VK_WHOLE_SIZE, // VkDeviceSize size;
5100 };
5101
5102 // Record command buffer.
5103 const vk::VkDeviceSize vertexBufferOffset = 0u;
5104 const auto renderArea = vk::makeRect2D(kWidth32, kHeight32);
5105 PushConstants pushConstants = { static_cast<int>(kWidth), static_cast<int>(kHeight), 0 };
5106
5107 vk::beginCommandBuffer(vkd, cmdBuffer);
5108
5109 // Render output buffers.
5110 vk::beginRenderPass(vkd, cmdBuffer, renderPassSingleSubpass.get(), framebufferSingleSubpass.get(), renderArea);
5111 for (size_t i = 0; i < outputBuffers.size(); ++i)
5112 {
5113 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, outputPipelines[i].getPipeline());
5114 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &outputSets[i].get(), 0u, nullptr);
5115 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
5116 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
5117 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
5118 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
5119 }
5120 vk::endRenderPass(vkd, cmdBuffer);
5121 for (size_t i = 0; i < outputBuffers.size(); ++i)
5122 {
5123 storageBufferDevToHostBarrier.buffer = outputBuffers[i]->get();
5124 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
5125 }
5126
5127 // Render reference buffers.
5128 vk::beginRenderPass(vkd, cmdBuffer, renderPassMultiplePasses.get(), framebufferMultiplePasses.get(), renderArea);
5129 for (size_t i = 0; i < referenceBuffers.size(); ++i)
5130 {
5131 if (i > 0)
5132 vkd.cmdNextSubpass(cmdBuffer, vk::VK_SUBPASS_CONTENTS_INLINE);
5133 vkd.cmdBindPipeline(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, referencePipelines[i].getPipeline());
5134 vkd.cmdBindDescriptorSets(cmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, 1u, &referenceSets[i].get(), 0u, nullptr);
5135 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBuffer.get(), &vertexBufferOffset);
5136 pushConstants.samples = static_cast<int>(m_params.subpassCounts[i]);
5137 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), pushConstantRange.stageFlags, pushConstantRange.offset, pushConstantRange.size, &pushConstants);
5138 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(vertices.size()), 1u, 0u, 0u);
5139 }
5140 vk::endRenderPass(vkd, cmdBuffer);
5141 for (size_t i = 0; i < referenceBuffers.size(); ++i)
5142 {
5143 storageBufferDevToHostBarrier.buffer = referenceBuffers[i]->get();
5144 vkd.cmdPipelineBarrier(cmdBuffer, vk::VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 1u, &storageBufferDevToHostBarrier, 0u, nullptr);
5145 }
5146
5147 vk::endCommandBuffer(vkd, cmdBuffer);
5148
5149 // Run all pipelines.
5150 vk::submitCommandsAndWait(vkd, device, queue, cmdBuffer);
5151
5152 // Invalidate reference allocs.
5153 #undef LOG_BUFFER_CONTENTS
5154 #ifdef LOG_BUFFER_CONTENTS
5155 auto& log = m_context.getTestContext().getLog();
5156 #endif
5157 for (size_t i = 0; i < referenceBuffers.size(); ++i)
5158 {
5159 auto& buffer = referenceBuffers[i];
5160 auto& alloc = buffer->getAllocation();
5161 vk::invalidateAlloc(vkd, device, alloc);
5162
5163 #ifdef LOG_BUFFER_CONTENTS
5164 std::vector<deInt32> bufferValues(bufferNumElements[i]);
5165 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
5166
5167 std::ostringstream msg;
5168 for (const auto value : bufferValues)
5169 msg << " " << value;
5170 log << tcu::TestLog::Message << "Reference buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
5171 #endif
5172 }
5173
5174 for (size_t i = 0; i < outputBuffers.size(); ++i)
5175 {
5176 auto& buffer = outputBuffers[i];
5177 auto& alloc = buffer->getAllocation();
5178 vk::invalidateAlloc(vkd, device, alloc);
5179
5180 #ifdef LOG_BUFFER_CONTENTS
5181 std::vector<deInt32> bufferValues(bufferNumElements[i]);
5182 deMemcpy(bufferValues.data(), alloc.getHostPtr(), bufferSizes[i]);
5183
5184 std::ostringstream msg;
5185 for (const auto value : bufferValues)
5186 msg << " " << value;
5187 log << tcu::TestLog::Message << "Output buffer values with " << m_params[i] << " samples:" << msg.str() << tcu::TestLog::EndMessage;
5188 #endif
5189
5190 if (deMemCmp(alloc.getHostPtr(), referenceBuffers[i]->getAllocation().getHostPtr(), static_cast<size_t>(bufferSizes[i])) != 0)
5191 return tcu::TestStatus::fail("Buffer mismatch in output buffer " + de::toString(i));
5192 }
5193
5194 return tcu::TestStatus::pass("Pass");
5195 }
5196
5197 using ElementsVector = std::vector<vk::VkSampleCountFlagBits>;
5198 using CombinationVector = std::vector<ElementsVector>;
5199
combinationsRecursive(const ElementsVector & elements,size_t requestedSize,CombinationVector & solutions,ElementsVector & partial)5200 void combinationsRecursive(const ElementsVector& elements, size_t requestedSize, CombinationVector& solutions, ElementsVector& partial)
5201 {
5202 if (partial.size() == requestedSize)
5203 solutions.push_back(partial);
5204 else
5205 {
5206 for (const auto& elem : elements)
5207 {
5208 partial.push_back(elem);
5209 combinationsRecursive(elements, requestedSize, solutions, partial);
5210 partial.pop_back();
5211 }
5212 }
5213 }
5214
combinations(const ElementsVector & elements,size_t requestedSize)5215 CombinationVector combinations(const ElementsVector& elements, size_t requestedSize)
5216 {
5217 CombinationVector solutions;
5218 ElementsVector partial;
5219
5220 combinationsRecursive(elements, requestedSize, solutions, partial);
5221 return solutions;
5222 }
5223
5224 } // anonymous
5225
createMultisampleTests(tcu::TestContext & testCtx,PipelineConstructionType pipelineConstructionType,bool useFragmentShadingRate)5226 tcu::TestCaseGroup* createMultisampleTests (tcu::TestContext& testCtx, PipelineConstructionType pipelineConstructionType, bool useFragmentShadingRate)
5227 {
5228 const VkSampleCountFlagBits samples[] =
5229 {
5230 VK_SAMPLE_COUNT_2_BIT,
5231 VK_SAMPLE_COUNT_4_BIT,
5232 VK_SAMPLE_COUNT_8_BIT,
5233 VK_SAMPLE_COUNT_16_BIT,
5234 VK_SAMPLE_COUNT_32_BIT,
5235 VK_SAMPLE_COUNT_64_BIT
5236 };
5237
5238 const char* groupName[] { "multisample", "multisample_with_fragment_shading_rate" };
5239 de::MovePtr<tcu::TestCaseGroup> multisampleTests (new tcu::TestCaseGroup(testCtx, groupName[useFragmentShadingRate], ""));
5240
5241 // Rasterization samples tests
5242 {
5243 de::MovePtr<tcu::TestCaseGroup> rasterizationSamplesTests(new tcu::TestCaseGroup(testCtx, "raster_samples", ""));
5244
5245 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5246 {
5247 std::ostringstream caseName;
5248 caseName << "samples_" << samples[samplesNdx];
5249
5250 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5251
5252 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5253 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5254 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5255 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, 0u, useFragmentShadingRate));
5256
5257 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "depth", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_DEPTH_BIT, useFragmentShadingRate));
5258 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "stencil", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, TEST_MODE_STENCIL_BIT, useFragmentShadingRate));
5259 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));
5260
5261 #ifndef CTS_USES_VULKANSC
5262 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_triangle_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5263 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_line_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5264 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_1px_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5265 samplesTests->addChild(new RasterizationSamplesTest(testCtx, "primitive_point_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, 0u, useFragmentShadingRate));
5266
5267 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));
5268 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));
5269 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));
5270 #endif // CTS_USES_VULKANSC
5271 rasterizationSamplesTests->addChild(samplesTests.release());
5272 }
5273
5274 multisampleTests->addChild(rasterizationSamplesTests.release());
5275 }
5276
5277 // Raster samples consistency check
5278 #ifndef CTS_USES_VULKANSC
5279 {
5280 de::MovePtr<tcu::TestCaseGroup> rasterSamplesConsistencyTests (new tcu::TestCaseGroup(testCtx, "raster_samples_consistency", ""));
5281 MultisampleTestParams paramsRegular = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate };
5282 MultisampleTestParams paramsSparse = { pipelineConstructionType, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate };
5283
5284 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
5285 "unique_colors_check",
5286 "",
5287 checkSupport,
5288 initMultisamplePrograms,
5289 testRasterSamplesConsistency,
5290 paramsRegular);
5291 addFunctionCaseWithPrograms(rasterSamplesConsistencyTests.get(),
5292 "unique_colors_check_sparse",
5293 "",
5294 checkSupport,
5295 initMultisamplePrograms,
5296 testRasterSamplesConsistency,
5297 paramsSparse);
5298 multisampleTests->addChild(rasterSamplesConsistencyTests.release());
5299
5300 }
5301 #endif // CTS_USES_VULKANSC
5302
5303 // minSampleShading tests
5304 {
5305 struct TestConfig
5306 {
5307 const char* name;
5308 float minSampleShading;
5309 };
5310
5311 const TestConfig testConfigs[] =
5312 {
5313 { "min_0_0", 0.0f },
5314 { "min_0_25", 0.25f },
5315 { "min_0_5", 0.5f },
5316 { "min_0_75", 0.75f },
5317 { "min_1_0", 1.0f }
5318 };
5319
5320 {
5321 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading", ""));
5322
5323 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5324 {
5325 const TestConfig& testConfig = testConfigs[configNdx];
5326 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5327
5328 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5329 {
5330 std::ostringstream caseName;
5331 caseName << "samples_" << samples[samplesNdx];
5332
5333 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5334
5335 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_triangle", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5336 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_line", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5337 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));
5338 samplesTests->addChild(new MinSampleShadingTest(testCtx, "primitive_point", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5339 #ifndef CTS_USES_VULKANSC
5340 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));
5341 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));
5342 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));
5343 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));
5344 #endif // CTS_USES_VULKANSC
5345
5346 minShadingValueTests->addChild(samplesTests.release());
5347 }
5348
5349 minSampleShadingTests->addChild(minShadingValueTests.release());
5350 }
5351
5352 multisampleTests->addChild(minSampleShadingTests.release());
5353 }
5354
5355 {
5356 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_enabled", ""));
5357
5358 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5359 {
5360 const TestConfig& testConfig = testConfigs[configNdx];
5361 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5362
5363 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5364 {
5365 std::ostringstream caseName;
5366 caseName << "samples_" << samples[samplesNdx];
5367
5368 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5369
5370 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, true, useFragmentShadingRate));
5371
5372 minShadingValueTests->addChild(samplesTests.release());
5373 }
5374
5375 minSampleShadingTests->addChild(minShadingValueTests.release());
5376 }
5377
5378 multisampleTests->addChild(minSampleShadingTests.release());
5379 }
5380
5381 {
5382 de::MovePtr<tcu::TestCaseGroup> minSampleShadingTests(new tcu::TestCaseGroup(testCtx, "min_sample_shading_disabled", ""));
5383
5384 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5385 {
5386 const TestConfig& testConfig = testConfigs[configNdx];
5387 de::MovePtr<tcu::TestCaseGroup> minShadingValueTests (new tcu::TestCaseGroup(testCtx, testConfigs[configNdx].name, ""));
5388
5389 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5390 {
5391 std::ostringstream caseName;
5392 caseName << "samples_" << samples[samplesNdx];
5393
5394 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5395
5396 samplesTests->addChild(new MinSampleShadingTest(testCtx, "quad", "", pipelineConstructionType, samples[samplesNdx], testConfig.minSampleShading, GEOMETRY_TYPE_OPAQUE_QUAD, 1.0f, IMAGE_BACKING_MODE_REGULAR, false, useFragmentShadingRate));
5397
5398 minShadingValueTests->addChild(samplesTests.release());
5399 }
5400
5401 minSampleShadingTests->addChild(minShadingValueTests.release());
5402 }
5403
5404 multisampleTests->addChild(minSampleShadingTests.release());
5405 }
5406 }
5407
5408 // SampleMask tests
5409 {
5410 struct TestConfig
5411 {
5412 const char* name;
5413 const char* description;
5414 VkSampleMask sampleMask;
5415 };
5416
5417 const TestConfig testConfigs[] =
5418 {
5419 { "mask_all_on", "All mask bits are off", 0x0 },
5420 { "mask_all_off", "All mask bits are on", 0xFFFFFFFF },
5421 { "mask_one", "All mask elements are 0x1", 0x1},
5422 { "mask_random", "All mask elements are 0xAAAAAAAA", 0xAAAAAAAA },
5423 };
5424
5425 de::MovePtr<tcu::TestCaseGroup> sampleMaskTests(new tcu::TestCaseGroup(testCtx, "sample_mask", ""));
5426
5427 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5428 {
5429 const TestConfig& testConfig = testConfigs[configNdx];
5430 de::MovePtr<tcu::TestCaseGroup> sampleMaskValueTests (new tcu::TestCaseGroup(testCtx, testConfig.name, testConfig.description));
5431
5432 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5433 {
5434 std::ostringstream caseName;
5435 caseName << "samples_" << samples[samplesNdx];
5436
5437 const deUint32 sampleMaskCount = samples[samplesNdx] / 32;
5438 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5439
5440 std::vector<VkSampleMask> mask;
5441 for (deUint32 maskNdx = 0; maskNdx < sampleMaskCount; maskNdx++)
5442 mask.push_back(testConfig.sampleMask);
5443
5444 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5445 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5446 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5447 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5448 #ifndef CTS_USES_VULKANSC
5449 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_triangle_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_TRIANGLE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5450 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_line_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_LINE, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5451 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_1px_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 1.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5452 samplesTests->addChild(new SampleMaskTest(testCtx, "primitive_point_sparse", "", pipelineConstructionType, samples[samplesNdx], mask, GEOMETRY_TYPE_OPAQUE_POINT, 3.0f, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5453 #endif // CTS_USES_VULKANSC
5454
5455 sampleMaskValueTests->addChild(samplesTests.release());
5456 }
5457
5458 sampleMaskTests->addChild(sampleMaskValueTests.release());
5459 }
5460
5461 multisampleTests->addChild(sampleMaskTests.release());
5462
5463 }
5464
5465 // AlphaToOne tests
5466 {
5467 const VkSampleCountFlagBits samplesForAlphaToOne[] =
5468 {
5469 VK_SAMPLE_COUNT_1_BIT,
5470 VK_SAMPLE_COUNT_2_BIT,
5471 VK_SAMPLE_COUNT_4_BIT,
5472 VK_SAMPLE_COUNT_8_BIT,
5473 VK_SAMPLE_COUNT_16_BIT,
5474 VK_SAMPLE_COUNT_32_BIT,
5475 VK_SAMPLE_COUNT_64_BIT
5476 };
5477 de::MovePtr<tcu::TestCaseGroup> alphaToOneTests(new tcu::TestCaseGroup(testCtx, "alpha_to_one", ""));
5478
5479 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samplesForAlphaToOne); samplesNdx++)
5480 {
5481 std::ostringstream caseName;
5482 caseName << "samples_" << samplesForAlphaToOne[samplesNdx];
5483
5484 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5485 #ifndef CTS_USES_VULKANSC
5486 caseName << "_sparse";
5487 alphaToOneTests->addChild(new AlphaToOneTest(testCtx, caseName.str(), "", pipelineConstructionType, samplesForAlphaToOne[samplesNdx], IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5488 #endif // CTS_USES_VULKANSC
5489 }
5490
5491 multisampleTests->addChild(alphaToOneTests.release());
5492 }
5493
5494 // AlphaToCoverageEnable tests
5495 {
5496 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage", ""));
5497
5498 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5499 {
5500 std::ostringstream caseName;
5501 caseName << "samples_" << samples[samplesNdx];
5502
5503 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5504
5505 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5506 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5507 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5508 #ifndef CTS_USES_VULKANSC
5509 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5510 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_translucent_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_TRANSLUCENT_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5511 samplesTests->addChild(new AlphaToCoverageTest(testCtx, "alpha_invisible_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5512 #endif // CTS_USES_VULKANSC
5513
5514 alphaToCoverageTests->addChild(samplesTests.release());
5515 }
5516 multisampleTests->addChild(alphaToCoverageTests.release());
5517 }
5518
5519 // AlphaToCoverageEnable without color buffer tests
5520 {
5521 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageNoColorAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_no_color_attachment", ""));
5522
5523 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5524 {
5525 std::ostringstream caseName;
5526 caseName << "samples_" << samples[samplesNdx];
5527
5528 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5529
5530 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5531 #ifndef CTS_USES_VULKANSC
5532 samplesTests->addChild(new AlphaToCoverageNoColorAttachmentTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5533 #endif // CTS_USES_VULKANSC
5534
5535 alphaToCoverageNoColorAttachmentTests->addChild(samplesTests.release());
5536 }
5537 multisampleTests->addChild(alphaToCoverageNoColorAttachmentTests.release());
5538 }
5539
5540 // AlphaToCoverageEnable with unused color attachment:
5541 // Set color output at location 0 as unused, but use the alpha write to control coverage for rendering to color buffer at location 1.
5542 {
5543 de::MovePtr<tcu::TestCaseGroup> alphaToCoverageColorUnusedAttachmentTests (new tcu::TestCaseGroup(testCtx, "alpha_to_coverage_unused_attachment", ""));
5544
5545 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(samples); samplesNdx++)
5546 {
5547 std::ostringstream caseName;
5548 caseName << "samples_" << samples[samplesNdx];
5549
5550 de::MovePtr<tcu::TestCaseGroup> samplesTests (new tcu::TestCaseGroup(testCtx, caseName.str().c_str(), ""));
5551
5552 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5553 #ifndef CTS_USES_VULKANSC
5554 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_opaque_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_OPAQUE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5555 #endif // CTS_USES_VULKANSC
5556 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_REGULAR, useFragmentShadingRate));
5557 #ifndef CTS_USES_VULKANSC
5558 samplesTests->addChild(new AlphaToCoverageColorUnusedAttachmentTest(testCtx, "alpha_invisible_sparse", "", pipelineConstructionType, samples[samplesNdx], GEOMETRY_TYPE_INVISIBLE_QUAD, IMAGE_BACKING_MODE_SPARSE, useFragmentShadingRate));
5559 #endif // CTS_USES_VULKANSC
5560
5561 alphaToCoverageColorUnusedAttachmentTests->addChild(samplesTests.release());
5562 }
5563 multisampleTests->addChild(alphaToCoverageColorUnusedAttachmentTests.release());
5564 }
5565
5566 #ifndef CTS_USES_VULKANSC
5567 // not all tests need to be repeated for FSR
5568 if (useFragmentShadingRate == false)
5569 {
5570 // Sampling from a multisampled image texture (texelFetch)
5571 multisampleTests->addChild(createMultisampleSampledImageTests(testCtx, pipelineConstructionType));
5572
5573 // Load/store on a multisampled rendered image (different kinds of access: color attachment write, storage image, etc.)
5574 multisampleTests->addChild(createMultisampleStorageImageTests(testCtx, pipelineConstructionType));
5575
5576 // Sampling from a multisampled image texture (texelFetch), checking supersample positions
5577 multisampleTests->addChild(createMultisampleStandardSamplePositionTests(testCtx, pipelineConstructionType));
5578
5579 // VK_AMD_shader_fragment_mask
5580 multisampleTests->addChild(createMultisampleShaderFragmentMaskTests(testCtx, pipelineConstructionType));
5581
5582 // Multisample resolve tests where a render area is less than an attachment size.
5583 multisampleTests->addChild(createMultisampleResolveRenderpassRenderAreaTests(testCtx, pipelineConstructionType));
5584
5585 // VK_EXT_multisampled_render_to_single_sampled
5586 {
5587 multisampleTests->addChild(createMultisampledRenderToSingleSampledTests(testCtx, pipelineConstructionType));
5588 // Take advantage of the code for this extension's tests to add some normal multisampling tests
5589 multisampleTests->addChild(createMultisampledMiscTests(testCtx, pipelineConstructionType));
5590 }
5591 }
5592
5593 // VK_EXT_sample_locations
5594 multisampleTests->addChild(createMultisampleSampleLocationsExtTests(testCtx, pipelineConstructionType, useFragmentShadingRate));
5595
5596 // VK_AMD_mixed_attachment
5597 multisampleTests->addChild(createMultisampleMixedAttachmentSamplesTests(testCtx, pipelineConstructionType, useFragmentShadingRate));
5598
5599 // Sample mask with and without vk_ext_post_depth_coverage
5600 {
5601 const vk::VkSampleCountFlagBits standardSamplesSet[] =
5602 {
5603 vk::VK_SAMPLE_COUNT_2_BIT,
5604 vk::VK_SAMPLE_COUNT_4_BIT,
5605 vk::VK_SAMPLE_COUNT_8_BIT,
5606 vk::VK_SAMPLE_COUNT_16_BIT
5607 };
5608
5609 de::MovePtr<tcu::TestCaseGroup> sampleMaskWithDepthTestGroup(new tcu::TestCaseGroup(testCtx, "sample_mask_with_depth_test", ""));
5610
5611 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++ndx)
5612 {
5613 std::ostringstream caseName;
5614 caseName << "samples_" << standardSamplesSet[ndx];
5615
5616 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", pipelineConstructionType, standardSamplesSet[ndx], false, useFragmentShadingRate));
5617
5618 caseName << "_post_depth_coverage";
5619 sampleMaskWithDepthTestGroup->addChild(new SampleMaskWithDepthTestTest(testCtx, caseName.str(), "", pipelineConstructionType, standardSamplesSet[ndx], true, useFragmentShadingRate));
5620
5621 }
5622 multisampleTests->addChild(sampleMaskWithDepthTestGroup.release());
5623 }
5624 #endif // CTS_USES_VULKANSC
5625
5626 {
5627 //Conservative rasterization test
5628 struct TestConfig
5629 {
5630 const char* name;
5631 const char* description;
5632 bool enableMinSampleShading;
5633 const float minSampleShading;
5634 const bool enableSampleMask;
5635 VkSampleMask sampleMask;
5636 bool enablePostDepthCoverage;
5637 };
5638
5639 const TestConfig testConfigs[] =
5640 {
5641 { "plain_conservative", "Only conservative rendering applied", false, 0.0f, false, 0x0, false },
5642 { "post_depth_coverage", "Post depth coverage enabled", false, 0.0f, false, 0x0, true },
5643 { "min_0_25", "minSampleMask set to 0.25f", true, 0.25f, false, 0x0, false },
5644 { "min_0_5", "minSampleMask set to 0.5f", true, 0.5f, false, 0x0, false },
5645 { "min_0_75", "minSampleMask set to 0.75f", true, 0.75f, false, 0x0, false },
5646 { "min_0_1_0", "minSampleMask set to 1.0f", true, 1.0f, false, 0x0, false },
5647 { "mask_all_off", "All mask bits are on", false, 0.0f, true, 0x0, false },
5648 { "mask_all_on", "All mask bits are off", false, 0.0f, true, 0xFFFFFFFF, false },
5649 { "mask_half_on", "All mask elements are 0xAAAAAAAA", false, 0.0f, true, 0xAAAAAAAA, false },
5650 };
5651
5652 const vk::VkSampleCountFlagBits standardSamplesSet[] =
5653 {
5654 vk::VK_SAMPLE_COUNT_2_BIT,
5655 vk::VK_SAMPLE_COUNT_4_BIT,
5656 vk::VK_SAMPLE_COUNT_8_BIT,
5657 vk::VK_SAMPLE_COUNT_16_BIT
5658 };
5659
5660 enum vk::VkConservativeRasterizationModeEXT rasterizationMode[] =
5661 {
5662 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_OVERESTIMATE_EXT,
5663 vk::VK_CONSERVATIVE_RASTERIZATION_MODE_UNDERESTIMATE_EXT
5664 };
5665
5666 // Conservative rendering
5667 de::MovePtr<tcu::TestCaseGroup> conservativeGroup(new tcu::TestCaseGroup(testCtx, "conservative_with_full_coverage", ""));
5668
5669 for (int modeNdx = 0; modeNdx < DE_LENGTH_OF_ARRAY(rasterizationMode); ++modeNdx)
5670 {
5671 const char* modeName = (modeNdx == 0 ? "overestimate" : "underestimate");
5672 de::MovePtr<tcu::TestCaseGroup> modesGroup(new tcu::TestCaseGroup(testCtx, modeName, ""));
5673
5674 for (int samplesNdx = 0; samplesNdx < DE_LENGTH_OF_ARRAY(standardSamplesSet); ++samplesNdx)
5675 {
5676 std::string caseName = "samples_" + std::to_string(standardSamplesSet[samplesNdx]) + "_";
5677
5678 for (int configNdx = 0; configNdx < DE_LENGTH_OF_ARRAY(testConfigs); configNdx++)
5679 {
5680 const TestConfig& testConfig = testConfigs[configNdx];
5681
5682 modesGroup->addChild(new SampleMaskWithConservativeTest(testCtx, caseName + testConfig.name, testConfig.description, pipelineConstructionType, standardSamplesSet[samplesNdx],
5683 rasterizationMode[modeNdx], testConfig.enableMinSampleShading, testConfig.minSampleShading, testConfig.enableSampleMask,
5684 testConfig.sampleMask, testConfig.enablePostDepthCoverage, useFragmentShadingRate));
5685 }
5686
5687 }
5688
5689 conservativeGroup->addChild(modesGroup.release());
5690 }
5691
5692 multisampleTests->addChild(conservativeGroup.release());
5693 }
5694
5695 {
5696 static const std::vector<vk::VkSampleCountFlagBits> kSampleCounts =
5697 {
5698 vk::VK_SAMPLE_COUNT_1_BIT,
5699 vk::VK_SAMPLE_COUNT_2_BIT,
5700 vk::VK_SAMPLE_COUNT_4_BIT,
5701 vk::VK_SAMPLE_COUNT_8_BIT,
5702 vk::VK_SAMPLE_COUNT_16_BIT,
5703 vk::VK_SAMPLE_COUNT_32_BIT,
5704 vk::VK_SAMPLE_COUNT_64_BIT,
5705 };
5706
5707
5708 static const std::array<bool, 2> unusedAttachmentFlag = {{ false, true }};
5709
5710 {
5711 de::MovePtr<tcu::TestCaseGroup> variableRateGroup(new tcu::TestCaseGroup(testCtx, "variable_rate", "Tests for multisample variable rate in subpasses"));
5712
5713 // 2 and 3 subpasses should be good enough.
5714 static const std::vector<size_t> combinationSizes = { 2, 3 };
5715
5716 // Basic cases.
5717 for (const auto size : combinationSizes)
5718 {
5719 const auto combs = combinations(kSampleCounts, size);
5720 for (const auto& comb : combs)
5721 {
5722 // Check sample counts actually vary between some of the subpasses.
5723 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
5724 if (uniqueVals.size() < 2)
5725 continue;
5726
5727 std::ostringstream name;
5728 std::ostringstream desc;
5729
5730 bool first = true;
5731 for (const auto& count : comb)
5732 {
5733 name << (first ? "" : "_") << count;
5734 desc << (first ? "Subpasses with counts " : ", ") << count;
5735 first = false;
5736 }
5737
5738 const VariableRateTestCase::TestParams params =
5739 {
5740 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
5741 false, // bool nonEmptyFramebuffer;
5742 vk::VK_SAMPLE_COUNT_1_BIT, // vk::VkSampleCountFlagBits fbCount;
5743 false, // bool unusedAttachment;
5744 comb, // SampleCounts subpassCounts;
5745 useFragmentShadingRate, // bool useFragmentShadingRate;
5746 };
5747 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
5748 }
5749 }
5750
5751 // Cases with non-empty framebuffers: only 2 subpasses to avoid a large number of combinations.
5752 {
5753 // Use one more sample count for the framebuffer attachment. It will be taken from the last item.
5754 auto combs = combinations(kSampleCounts, 2 + 1);
5755 for (auto& comb : combs)
5756 {
5757 // Framebuffer sample count.
5758 const auto fbCount = comb.back();
5759 comb.pop_back();
5760
5761 // Check sample counts actually vary between some of the subpasses.
5762 std::set<vk::VkSampleCountFlagBits> uniqueVals(begin(comb), end(comb));
5763 if (uniqueVals.size() < 2)
5764 continue;
5765
5766 for (const auto flag : unusedAttachmentFlag)
5767 {
5768 std::ostringstream name;
5769 std::ostringstream desc;
5770
5771 desc << "Framebuffer with sample count " << fbCount << " and subpasses with counts ";
5772
5773 bool first = true;
5774 for (const auto& count : comb)
5775 {
5776 name << (first ? "" : "_") << count;
5777 desc << (first ? "" : ", ") << count;
5778 first = false;
5779 }
5780
5781 name << "_fb_" << fbCount;
5782
5783 if (flag)
5784 {
5785 name << "_unused";
5786 desc << " and unused attachments";
5787 }
5788
5789 const VariableRateTestCase::TestParams params =
5790 {
5791 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
5792 true, // bool nonEmptyFramebuffer;
5793 fbCount, // vk::VkSampleCountFlagBits fbCount;
5794 flag, // bool unusedAttachment;
5795 comb, // SampleCounts subpassCounts;
5796 useFragmentShadingRate, // bool useFragmentShadingRate;
5797 };
5798 variableRateGroup->addChild(new VariableRateTestCase(testCtx, name.str(), desc.str(), params));
5799 }
5800 }
5801 }
5802
5803 multisampleTests->addChild(variableRateGroup.release());
5804 }
5805
5806 {
5807 de::MovePtr<tcu::TestCaseGroup> mixedCountGroup(new tcu::TestCaseGroup(testCtx, "mixed_count", "Tests for mixed sample count in empty subpass and framebuffer"));
5808
5809 const auto combs = combinations(kSampleCounts, 2);
5810 for (const auto& comb : combs)
5811 {
5812 // Check different sample count.
5813 DE_ASSERT(comb.size() == 2u);
5814 const auto& fbCount = comb[0];
5815 const auto& emptyCount = comb[1];
5816
5817 if (fbCount == emptyCount)
5818 continue;
5819
5820 const std::string fbCountStr = de::toString(fbCount);
5821 const std::string emptyCountStr = de::toString(emptyCount);
5822
5823 for (const auto flag : unusedAttachmentFlag)
5824 {
5825 const std::string nameSuffix = (flag ? "unused" : "");
5826 const std::string descSuffix = (flag ? "one unused attachment reference" : "no attachment references");
5827 const std::string name = fbCountStr + "_" + emptyCountStr + (nameSuffix.empty() ? "" : "_") + nameSuffix;
5828 const std::string desc = "Framebuffer with " + fbCountStr + " samples, subpass with " + emptyCountStr + " samples and " + descSuffix;
5829
5830 const VariableRateTestCase::TestParams params
5831 {
5832 pipelineConstructionType, // PipelineConstructionType pipelineConstructionType;
5833 true, // bool nonEmptyFramebuffer;
5834 fbCount, // vk::VkSampleCountFlagBits fbCount;
5835 flag, // bool unusedAttachment;
5836 VariableRateTestCase::SampleCounts(1u, emptyCount), // SampleCounts subpassCounts;
5837 useFragmentShadingRate, // bool useFragmentShadingRate;
5838 };
5839 mixedCountGroup->addChild(new VariableRateTestCase(testCtx, name, desc, params));
5840 }
5841 }
5842
5843 multisampleTests->addChild(mixedCountGroup.release());
5844 }
5845 }
5846
5847 return multisampleTests.release();
5848 }
5849
5850 } // pipeline
5851 } // vkt
5852