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