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