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