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